[Python学习篇] Python Socket网络编程

Python中的socket编程是通过内置的socket模块实现的,可以方便地创建网络应用程序,包括客户端和服务器。

服务端

1. 创建套接字

使用socket.socket()函数创建一个TCP套接字。套接字可以是流式(TCP)或数据报式(UDP)

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

  • socket.AF_INET:表示使用IPv4地址。
  • socket.SOCK_STREAM:表示套接字类型为流式套接字,即TCP。

2. 绑定地址和端口

使用bind()方法将套接字绑定到特定的IP地址和端口号上,以便客户端能够连接到该地址和端口。IP可以不指定表示本机地址。

server_address = ('localhost', 8080)

server_socket.bind(server_address)

3. 监听连接请求

使用listen()方法开始监听客户端的连接请求。参数backlog指定等待连接的最大数量。当服务器忙于处理当前连接而不能立即处理新的连接请求时,这些新的连接请求将会被放入一个等待队列中,直到服务器有能力处理它们。backlog参数定义了这个等待队列的最大长度。

server_socket.listen(5) # 最多允许5个等待连接的请求

4. 接受客户端连接

使用accept()方法接受客户端的连接。该方法会阻塞程序,直到有客户端连接进来。一旦有连接,accept()方法返回一个新的套接字(client_socket)和客户端的地址信息(client_address)。

client_socket, client_address = server_socket.accept()

  • client_socket:是与客户端通信的新套接字。
  • client_address:是客户端的地址信息,通常是一个元组(IP地址, 端口号)。

5. 与客户端通信

使用返回的client_socket对象与客户端进行数据交换。可以使用recv()方法接收客户端发送的数据,recv方法会阻塞直到接收到数据,并使用sendall()方法发送响应给客户端。

data = client_socket.recv(1024) # 接收数据,指定缓冲区大小为1024字节

client_socket.sendall(data) # 发送响应数据给客户端

6. 关闭连接

当通信结束后,使用close()方法关闭客户端套接字和服务器套接字,释放资源。

server_socket.close() # 关闭服务器套接字

TCP socket服务器代码

示例:

python 复制代码
import socket
import threading

# 服务器地址和端口
SERVER_HOST = 'localhost'
SERVER_PORT = 12345


def handle_client(client_socket):
    try:
        # 接收客户端的数据
        data = client_socket.recv(1024)
        print(f'收到客户端消息: {data.decode()}')  # decode:把字节数据转换成字符串数据

        # 发送响应给客户端
        message = 'Hello 我是服务端!'
        client_socket.sendall(message.encode())  # encode:把字符串数据转换成字节数据
    except Exception as e:
        print(f'处理客户端连接时出错: {e}')
    finally:
        # 关闭客户端连接
        client_socket.close()


def start_server():
    # 创建TCP套接字
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置端口复用选项
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    try:
        # 绑定服务器地址和端口
        server_socket.bind((SERVER_HOST, SERVER_PORT))

        # 开始监听连接
        server_socket.listen(128)
        print(f'服务器启动,监听 {SERVER_HOST}:{SERVER_PORT}')

        while True:
            # 等待客户端连接
            client_socket, client_address = server_socket.accept()
            print(f'接受来自 {client_address} 的连接')

            # 使用线程处理客户端请求
            client_thread = threading.Thread(target=handle_client, args=(client_socket,))
            client_thread.start()

    except Exception as e:
        print(f'服务器启动失败: {e}')
    finally:
        # 关闭服务器套接字
        server_socket.close()


if __name__ == "__main__":
    start_server()

客户端

1. 创建套接字

使用socket.socket()函数创建一个TCP套接字。

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

  • socket.AF_INET:表示使用IPv4地址。
  • socket.SOCK_STREAM:表示套接字类型为流式套接字,即TCP。

2. 连接到服务器

使用connect()方法连接到服务器的地址和端口。

server_address = ('localhost', 12345) # 服务器地址和端口

client_socket.connect(server_address)

3. 发送数据

使用sendall()方法将数据发送到服务器。该方法确保数据被完整发送。

message = '我是客户端数据!'

client_socket.sendall(message.encode())

4. 接收数据

使用recv()方法从服务器接收数据,该方法会阻塞直到收到数据。参数指定接收缓冲区的大小。

data = client_socket.recv(1024)

print(f'收到服务器消息: {data.decode()}')

5. 关闭连接

使用close()方法关闭套接字,释放资源。

client_socket.close()

TCP socket客户端代码

示例:

python 复制代码
# client.py
import socket

# 服务器地址和端口
SERVER_HOST = 'localhost'
SERVER_PORT = 12345


def start_client():
    try:
        # 1. 创建TCP套接字
        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # 2. 连接服务器
        client_socket.connect((SERVER_HOST, SERVER_PORT))
        print(f'已连接到服务器 {SERVER_HOST}:{SERVER_PORT}')

        # 3. 发送数据给服务器
        message = 'Hello 我是客户端!'
        client_socket.sendall(message.encode())  # encode:把字符串数据转换成字节数据

        # 4. 接收服务器的响应
        data = client_socket.recv(1024)
        print(f'收到服务器消息: {data.decode()}')  # decode:把字节数据转换成字符串数据

    except Exception as e:
        print(f'客户端出错: {e}')
    finally:
        # 5. 关闭客户端套接字
        client_socket.close()


if __name__ == "__main__":
    start_client()

客户端不断开,接收用户输入信息发送到服务端

示例:

服务端代码

python 复制代码
# server.py
import socket
import threading

# 服务器地址和端口
SERVER_HOST = 'localhost'
SERVER_PORT = 12345


def handle_client(client_socket):
    try:
        while True:
            # 接收客户端的数据
            data = client_socket.recv(1024)
            if not data:
                break
            print(f'收到客户端消息: {data.decode()}')

            # 发送响应给客户端
            message = 'Echo: ' + data.decode()
            client_socket.sendall(message.encode())
    except Exception as e:
        print(f'处理客户端连接时出错: {e}')
    finally:
        # 关闭客户端连接
        client_socket.close()


def start_server():
    # 创建TCP套接字
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    try:
        # 绑定服务器地址和端口
        server_socket.bind((SERVER_HOST, SERVER_PORT))

        # 开始监听连接,请求等待队列的最大长度设置为128
        server_socket.listen(128)
        print(f'服务器启动,监听 {SERVER_HOST}:{SERVER_PORT} ...')

        while True:
            # 等待客户端连接
            client_socket, client_address = server_socket.accept()
            print(f'接受来自 {client_address} 的连接')

            # 使用线程处理客户端请求
            client_thread = threading.Thread(target=handle_client, args=(client_socket,))
            client_thread.start()

    except Exception as e:
        print(f'服务器启动失败: {e}')
    finally:
        # 关闭服务器套接字
        server_socket.close()


if __name__ == "__main__":
    start_server()

客户端代码

python 复制代码
# client.py
import socket

# 服务器地址和端口
SERVER_HOST = 'localhost'
SERVER_PORT = 12345


def start_client():
    try:
        # 创建TCP套接字
        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # 连接服务器
        client_socket.connect((SERVER_HOST, SERVER_PORT))
        print(f'已连接到服务器 {SERVER_HOST}:{SERVER_PORT}')

        while True:
            # 从用户获取输入
            message = input('请输入发送给服务器的消息: ')

            # 发送数据到服务器
            client_socket.sendall(message.encode())

            # 接收服务器的响应
            data = client_socket.recv(1024)
            print(f'收到服务器消息: {data.decode()}')

    except Exception as e:
        print(f'客户端出错: {e}')
    finally:
        # 关闭客户端套接字
        client_socket.close()


if __name__ == "__main__":
    start_client()
相关推荐
乾元11 小时前
LLM 自动生成安全基线与等保合规初稿——把“网络工程事实”转译为“可审计的制度语言”
运维·网络·人工智能·python·安全·架构
全栈陈序员11 小时前
【Python】基础语法入门(二十四)——文件与目录操作进阶:安全、高效地处理本地数据
开发语言·人工智能·python·学习
是有头发的程序猿11 小时前
Python爬虫实战:面向对象编程构建高可维护的1688商品数据采集系统
开发语言·爬虫·python
摸鱼仙人~11 小时前
企业级 RAG 问答系统开发上线流程分析
后端·python·rag·检索
serve the people11 小时前
tensorflow tf.nn.softmax 核心解析
人工智能·python·tensorflow
癫狂的兔子11 小时前
【BUG】【Python】eval()报错
python·bug
啃火龙果的兔子11 小时前
java语言基础
java·开发语言·python
masterqwer11 小时前
day42打卡
python
不会飞的鲨鱼12 小时前
抖音验证码滑动轨迹原理(很难审核通过)
javascript·python
我命由我1234512 小时前
Python 开发问题:No Python interpreter configured for the project
开发语言·后端·python·学习·pycharm·学习方法·python3.11