socket
模块是 Python 中进行网络编程的核心,它提供了对 BSD Socket API 的低级访问接口,允许你实现各种网络协议的网络通信。它构成了像 http.client
、 urllib
以及许多流行框架(如 Django, Flask)背后网络通信的基础。
1. 核心概念:什么是 Socket?
可以把 Socket(套接字)想象成一个通信端点。就像你想通过电话联系某人,你需要一部电话机(Socket),一个电话号码(地址),然后进行拨号(连接)和通话(数据交换)。
- 端点:网络通信的一端。
- 地址:由 IP 地址(定位到主机)和 端口号(定位到主机上的具体应用程序)组成。例如
(‘192.168.1.10‘, 8080)
。 - 协议:最常用的是 TCP 和 UDP。
2. Socket 类型
socket
模块支持多种类型,最常用的是:
socket.SOCK_STREAM
:对应 TCP 协议。提供面向连接的、可靠的、基于字节流的通信。数据无差错、不丢失、不重复,且按序到达。像打电话,需要先建立稳定连接。socket.SOCK_DGRAM
:对应 UDP 协议。提供无连接的、不可靠的数据报服务。传输速度快,但不保证顺序和可靠性。像发短信,发送出去就不管了。
3. 核心工作流程(以 TCP 为例)
TCP 通信模型是典型的 客户端/服务器 模型。服务器等待连接,客户端发起连接。
服务器端 (Server)
服务器端的工作像一个公司的总机接线员。
- 创建 Socket
import socket
# 创建 TCP/IP socket
# AF_INET 表示使用 IPv4, 如果要 IPv6 则用 AF_INET6
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- 绑定地址和端口 (Bind)
将 Socket 与一个特定的网络接口和端口号绑定。
# 获取本地主机的名字,也可以直接使用 ‘localhost’ 或 ‘127.0.0.1’
host = socket.gethostname()
port = 12345
# 绑定端口
server_socket.bind((host, port))
- 监听连接 (Listen)
让 Socket 进入监听状态,等待客户端的连接请求。参数 5
指定最大排队等待连接的客户端数量。
server_socket.listen(5)
print(f"服务器在 {host}:{port} 上启动并开始监听...")
- 接受连接 (Accept)
这是一个阻塞调用,程序会暂停在这里,直到有客户端连接进来。当有连接时,它返回一个新的 Socket 对象 (client_socket
) 和客户端的地址。
client_socket, addr = server_socket.accept()
print(f"接收到来自 {addr} 的连接")
- 接收和发送数据
使用新返回的 client_socket
与这个特定的客户端进行通信。
# 接收数据 (阻塞)
data = client_socket.recv(1024) # 1024 是缓冲区大小,一次最多接收多少字节
print(f"从客户端接收到的消息: {data.decode(‘utf-8’)}")
# 发送数据
message = "你好!消息已收到。"
client_socket.send(message.encode(‘utf-8’))
- 关闭连接
client_socket.close() # 关闭与这个客户端的连接
server_socket.close() # 关闭服务器 socket (通常不会执行到这里,除非服务器关闭)