2.7 套接字编程:生成网络应用 | 《计算机网络:自顶向下方法》精读版
前面章节我们学习了应用层协议、进程通信等理论,而就是把这些理论落地为代码的 “编程接口”—— 它是应用层与运输层之间的 “桥梁”,让我们能在代码里直接调用 TCP/UDP 服务,实现真正的网络应用。
·
前面章节我们学习了应用层协议、进程通信等理论,而套接字(Socket) 就是把这些理论落地为代码的 “编程接口”—— 它是应用层与运输层之间的 “桥梁”,让我们能在代码里直接调用 TCP/UDP 服务,实现真正的网络应用。
2.7.1 UDP 套接字编程:无连接的高效通信
UDP 是无连接、不可靠的传输协议,对应到编程中,它的特点是 **“无需建立连接,直接发送数据”**,适合实时性要求高、对可靠性要求稍低的场景(如聊天、直播、DNS 查询)。
1. UDP 编程核心流程
以 Python 为例,UDP 通信分为服务器端和客户端:
服务器端(接收数据)
- 创建 UDP 套接字:
socket(AF_INET, SOCK_DGRAM)AF_INET:使用 IPv4 地址SOCK_DGRAM:指定为 UDP 类型
- 绑定端口:
bind((HOST, PORT)),监听指定端口的 incoming 数据 - 循环接收数据:
recvfrom(BUFSIZE),同时获取客户端地址 - 处理数据并回复(可选):
sendto(data, client_addr) - 关闭套接字
客户端(发送数据)
- 创建 UDP 套接字(和服务器端一致)
- 直接发送数据:
sendto(data, server_addr),无需提前连接 - 接收服务器回复(可选):
recvfrom(BUFSIZE) - 关闭套接字
2. 代码示例(Python)
# UDP 服务器
from socket import *
HOST = '127.0.0.1'
PORT = 12000
server_socket = socket(AF_INET, SOCK_DGRAM)
server_socket.bind((HOST, PORT))
print("UDP 服务器已启动,等待接收数据...")
while True:
data, client_addr = server_socket.recvfrom(1024)
print(f"收到来自 {client_addr} 的消息:{data.decode()}")
server_socket.sendto(f"已收到:{data.decode()}".encode(), client_addr)
server_socket.close()
# UDP 客户端
from socket import *
server_addr = ('127.0.0.1', 12000)
client_socket = socket(AF_INET, SOCK_DGRAM)
message = "Hello UDP!"
client_socket.sendto(message.encode(), server_addr)
response, _ = client_socket.recvfrom(1024)
print(f"服务器回复:{response.decode()}")
client_socket.close()
3. UDP 编程特点
- ✅ 无连接:客户端直接发送数据,不需要三次握手,开销小、速度快
- ❌ 不可靠:不保证数据一定送达,也不保证顺序,丢包不会重传
- ✅ 简单高效:代码逻辑简洁,适合实时性优先的场景
2.7.2 TCP 套接字编程:面向连接的可靠通信
TCP 是面向连接、可靠的传输协议,对应到编程中,它的特点是 **“先建立连接,再传输数据,保证可靠”**,适合对数据完整性要求高的场景(如文件传输、网页访问、邮件收发)。
1. TCP 编程核心流程
TCP 通信必须先建立连接,分为服务器端(被动监听)和客户端(主动连接):
服务器端(监听 + 处理连接)
- 创建 TCP 套接字:
socket(AF_INET, SOCK_STREAM)SOCK_STREAM:指定为 TCP 类型
- 绑定端口:
bind((HOST, PORT)) - 监听连接:
listen(backlog),backlog是等待连接的队列长度 - 接受连接:
conn, addr = accept(),阻塞等待客户端连接,返回连接套接字 - 通过连接套接字收发数据:
recv(BUFSIZE)/send(data) - 关闭连接套接字,继续监听下一个连接
客户端(主动连接)
- 创建 TCP 套接字(和服务器端一致)
- 连接服务器:
connect(server_addr),执行 TCP 三次握手 - 收发数据:
send(data)/recv(BUFSIZE) - 关闭套接字,执行 TCP 四次挥手
2. 代码示例(Python)
# TCP 服务器
from socket import *
HOST = '127.0.0.1'
PORT = 12000
server_socket = socket(AF_INET, SOCK_STREAM)
server_socket.bind((HOST, PORT))
server_socket.listen(5)
print("TCP 服务器已启动,等待客户端连接...")
while True:
conn_socket, client_addr = server_socket.accept()
print(f"客户端 {client_addr} 已连接")
data = conn_socket.recv(1024)
print(f"收到消息:{data.decode()}")
conn_socket.send(f"已收到:{data.decode()}".encode())
conn_socket.close()
server_socket.close()
# TCP 客户端
from socket import *
server_addr = ('127.0.0.1', 12000)
client_socket = socket(AF_INET, SOCK_STREAM)
client_socket.connect(server_addr)
message = "Hello TCP!"
client_socket.send(message.encode())
response = client_socket.recv(1024)
print(f"服务器回复:{response.decode()}")
client_socket.close()
3. TCP 编程特点
- ✅ 面向连接:必须先
connect()建立连接,才能传输数据 - ✅ 可靠传输:内置重传、排序、流量控制,保证数据完整送达
- ❌ 开销较大:三次握手、四次挥手、拥塞控制等机制会增加时延和资源消耗
- ✅ 流式传输:数据以字节流形式传输,没有边界,需要应用层自己处理消息边界
✅ UDP vs TCP 编程对比
| 特性 | UDP 套接字 | TCP 套接字 |
|---|---|---|
| 连接方式 | 无连接,直接发送 | 面向连接,必须先 connect() |
| 可靠性 | 不可靠,丢包不重传 | 可靠,保证数据完整有序 |
| 代码复杂度 | 简单,无需处理连接 | 稍复杂,需要监听、接受连接 |
| 适用场景 | 实时聊天、直播、DNS、游戏 | 文件传输、网页访问、邮件、数据库通信 |
| 核心 API | sendto() / recvfrom() |
connect() / send() / recv() |
🎯 编程实践建议
- 先跑通示例:把上面的 UDP/TCP 代码复制到本地运行,观察 “客户端发送→服务器接收→回复” 的完整流程
- 改造功能:
- 给 UDP 版本加一个简单的 “聊天功能”,让服务器可以广播消息给所有客户端
- 给 TCP 版本加 “文件传输” 功能,实现客户端上传文件到服务器
- 对比差异:故意断开网络,观察 UDP 丢包、TCP 重传的不同表现,加深对协议特性的理解
更多推荐



所有评论(0)