Python网络编码——聊天小工具
目录
基本概念
一、TCP(Transmission Control Protocol)
1. 核心特性
2. 三次握手流程
3. 四次挥手流程
4. 典型应用场景
二、UDP(User Datagram Protocol)
1. 核心特性
2. 数据报文结构
3. 典型应用场景
三、Socket
1. 概念本质
2. Socket 类型
3. 关键函数(以C为例)
4. 编程模型对比
四、核心对比表格
五、关键问题解析
六、总结建议
案例部署
TCP编程
UDP部署
基本概念
一、TCP(Transmission Control Protocol)
1. 核心特性
- 面向连接:通信前需通过 三次握手 建立连接,通信后通过 四次挥手 断开连接。
- 可靠传输:通过确认机制(ACK)、超时重传、流量控制(滑动窗口)和拥塞控制保证数据可靠性。
- 有序传输:数据按发送顺序到达接收端。
- 全双工通信:双方可同时发送和接收数据。
2. 三次握手流程
Client Server
|--- SYN=1, seq=x -->|
|<-- SYN=1, ACK=1, seq=y, ack=x+1 --|
|--- ACK=1, seq=x+1, ack=y+1 -->|
3. 四次挥手流程
Client Server
|--- FIN=1, seq=u -->|
|<-- ACK=1, seq=v, ack=u+1 --|
|<-- FIN=1, ACK=1, seq=w, ack=u+1 --|
|--- ACK=1, seq=u+1, ack=w+1 -->|
4. 典型应用场景
- Web 浏览器(HTTP/HTTPS)
- 文件传输(FTP)
- 电子邮件(SMTP/POP3)
二、UDP(User Datagram Protocol)
1. 核心特性
- 无连接:无需建立连接,直接发送数据。
- 不可靠传输:不保证数据到达、不保证顺序、不检测丢包。
- 高效性:头部仅 8 字节(TCP 头部 20-60 字节),传输开销小。
- 支持广播/组播:可同时向多个目标发送数据。
2. 数据报文结构
+--------+--------+--------+--------+
| Source Port | Destination Port |
| Length | Checksum |
| Data... |
+------------------------------------+
3. 典型应用场景
- 实时音视频传输(Zoom/Skype)
- DNS 查询
- 在线游戏(实时位置同步)
三、Socket
1. 概念本质
- 操作系统提供的网络编程接口:介于应用层和传输层之间的抽象层。
- 端点标识:由 IP 地址 + 端口号 唯一标识。
- 支持协议:可配置为 TCP 或 UDP 模式。
2. Socket 类型
类型 | 协议 | 特性 |
---|---|---|
SOCK_STREAM | TCP | 可靠、有序、面向连接 |
SOCK_DGRAM | UDP | 不可靠、无序、无连接 |
SOCK_RAW | - | 原始套接字(操作IP层) |
3. 关键函数(以C为例)
- TCP Server:
socket() -> bind() -> listen() -> accept() -> recv()/send()
- TCP Client:
socket() -> connect() -> send()/recv()
- UDP:
socket() -> bind() -> recvfrom()/sendto()
4. 编程模型对比
TCP | UDP | |
---|---|---|
连接性 | 需要维护连接状态 | 无状态 |
数据边界 | 流式数据(需处理粘包) | 数据报(自带边界) |
性能 | 高可靠性但延迟较高 | 低延迟但可能丢包 |
四、核心对比表格
特性 | TCP | UDP |
---|---|---|
连接方式 | 面向连接 | 无连接 |
可靠性 | 可靠传输(确认+重传) | 最大努力交付 |
数据顺序 | 保证顺序 | 不保证顺序 |
头部大小 | 20-60 字节 | 8 字节 |
传输速度 | 较慢(需握手和确认) | 极快 |
流量控制 | 滑动窗口机制 | 无 |
拥塞控制 | 多种算法(如Reno、Cubic) | 无 |
适用场景 | 文件传输、网页浏览 | 实时视频、DNS查询 |
五、关键问题解析
-
TCP粘包问题:
- 原因:TCP是字节流协议,不保留消息边界。
- 解决方案:
- 固定长度消息
- 分隔符(如
\n
) - 消息头声明长度(如HTTP协议)
-
UDP的可靠性实现:
- 需在应用层添加:序列号、确认机制、重传策略(类似QUIC协议)
-
Socket的复用技术:
- 端口复用:
setsockopt(SO_REUSEADDR)
- IO多路复用:select/poll/epoll(Linux)或 kqueue(BSD)
- 端口复用:
六、总结建议
- 选择TCP:当需要数据完整性和顺序性(如金融交易)
- 选择UDP:当需要低延迟和可容忍部分丢包(如直播、VoIP)
- Socket编程要点:
- TCP需处理连接生命周期
- UDP需处理报文分片(MTU限制)
- 始终考虑网络字节序转换(htonl/ntohl)
案例部署
TCP编程
服务端
代码如下,想偷懒就偷吧:
import sockethost='192.168.137.101'
port=33333s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#前为模块,后为函数,AF_INET表示IPv4,sock_stream表示TCP协议
s.bind((host,port))s.listen(1) #允许建立链接数sock,addr=s.accept()print('链接成功')info=sock.recv(1024).decode()
#允许接收数据文件大小,单位字节 decode[解码],encode【编码】while info != 'bye': #info:客户向服务端发送的消息if info:print('接收的信息为:'+info ) #+:变量的拼接send_data=input('输入信息:')send_data=str(send_data) #转化为纯字符串sock.send(send_data.encode())if send_data=='bye':breakinfo=sock.recv(1024).decode()
sock.close() #断开链接
s.close()
客户端
代码如下,想偷懒就偷懒吧
import socket
s=socket.socket()host='192.168.137.101'
port=33333s.connect((host,port))print('链接成功')info='' #客户info开始可定义为空
while info != 'bye':send_data=input('请输入相应的信息:')send_data=str (send_data)s.send(send_data.encode())if send_data =='bye':breakinfo=s.recv(1024).decode() #发送编码,接收解码print('接收信息为:' +info)
s.close()
UDP部署
服务端
代码如下:
import sockethost='192.168.137.101'
port=33333s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.bind((host,port))print("服务端已启动")while True:data,addr=s.recvfrom(1024)print(f"收到来自{addr}的消息:{data.decode()}")if data.decode() =='bye':breakreply =input("回复消息:")s.sendto(reply.encode(),addr)s.close
客户端
代码如下:
import sockethost='192.168.137.101'
port=33333s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)while True:msg=input("输入消息:")s.sendto(msg.encode(),(host,port))if msg =='bye':breakdata,addr=s.recvfrom(1024)print(f"收到回复:{data.decode()}")s.close()