socket
socket 模块提供了访问 BSD 套接字? 的接口,是所有现代 Unix 系统、Windows、macOS 和其他一些平台上进行网络编程的基础。
套接字协议族
根据系统以及构建选项,此模块提供了各种套接字协议簇。常用的协议族包括:
| 协议族 | 常量 | 地址格式 | 说明 |
|---|---|---|---|
| IPv4 | AF_INET | (host, port) 元组host: 主机名或 IPv4 地址字符串port: 整数端口号特殊值: '' 表示所有接口,'<broadcast>' 表示广播地址 | 用于 IPv4 网络通信 |
| IPv6 | AF_INET6 | (host, port, flowinfo, scope_id) 四元组host: IPv6 地址字符串port: 整数端口号flowinfo: 流信息(通常为 0)scope_id: 作用域 ID(通常为 0)简化形式: (host, port) | 用于 IPv6 网络通信 |
| Unix域 | AF_UNIX | 文件系统路径字符串 例如: '/tmp/mysocket.sock' | 用于同一台机器上的进程间通信 |
| 原始套接字 | AF_PACKET | 接口名称字符串 例如: 'eth0' | 用于底层网络包访问(Linux) |
| 蓝牙 | AF_BLUETOOTH | 蓝牙地址元组,格式取决于协议 | 用于蓝牙通信 |
地址格式示例
import socket
# AF_INET 地址示例
address_v4_1 = ('www.example.com', 80) # 使用主机名
address_v4_2 = ('192.168.1.1', 8080) # 使用 IPv4 地址
address_v4_3 = ('', 8080) # 绑定到所有接口 (INADDR_ANY)
address_v4_4 = ('<broadcast>', 8080) # 广播地址 (INADDR_BROADCAST)
# AF_INET6 地址示例
address_v6_1 = ('2001:0db8::1', 8080, 0, 0) # 完整形式
address_v6_2 = ('2001:0db8::1', 8080) # 简化形式(省略 flowinfo 和 scope_id)
# AF_UNIX 地址示例
address_unix = '/tmp/mysocket.sock' # Unix 域套接字路径
套接字类型
| 类型 | 常量 | 说明 |
|---|---|---|
| TCP流 | SOCK_STREAM | 面向连接的可靠传输,用于 TCP |
| UDP数据报 | SOCK_DGRAM | 无连接不可靠传输,用于 UDP |
| 原始套接字 | SOCK_RAW | 原始网络协议访问? |
warning
使用原始套接字需要管理员权限,且可以绕过操作系统的网络安全机制,可能被恶意软件利用。在生产环境中应谨慎使用。
工作流程
| 类型 | 工作流程 |
|---|---|
| TCP服务器 | 创建Socket → 绑定地址(bind) → 监听(listen) → 接受连接(accept) → 收发数据(send/recv) → 关闭Socket(close) |
| TCP客户端 | 创建Socket → 连接服务器(connect) → 收发数据(send/recv) → 关闭Socket(close) |
| UDP服务器 | 创建Socket → 绑定地址(bind) → 收发数据(recvfrom/sendto) → 关闭Socket(close) |
| UDP客户端 | 创建Socket → (可选绑定) → 收发数据(sendto/recvfrom) → 关闭Socket(close) |
| 原始套接字 | 创建Socket → 绑定地址(bind) → 设置选项(setsockopt) → 收发原始数据包 → 关闭Socket(close) |
tip
TCP 和 UDP 都是全双工通信,可以同时发送和接收数据。
- TCP 的
send/recv:建立连接后可以使用send()发送数据,使用recv()接收数据,两个操作可以交替或并发进行 - UDP 的
recvfrom/sendto:使用recvfrom()接收数据(返回数据和发送方地址),使用sendto()发送数据(需要指定目标地址)。UDP 无连接,每次发送都需指定地址