Python网络编码——聊天小工具
代码如下,想偷懒就偷懒吧。
·
目录
一、TCP(Transmission Control Protocol)
二、UDP(User Datagram Protocol)
基本概念
一、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 socket
host='192.168.137.101'
port=33333
s=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':
break
info=sock.recv(1024).decode()
sock.close() #断开链接
s.close()
客户端
代码如下,想偷懒就偷懒吧
import socket
s=socket.socket()
host='192.168.137.101'
port=33333
s.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':
break
info=s.recv(1024).decode() #发送编码,接收解码
print('接收信息为:' +info)
s.close()
UDP部署
服务端
代码如下:
import socket
host='192.168.137.101'
port=33333
s=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':
break
reply =input("回复消息:")
s.sendto(reply.encode(),addr)
s.close
客户端
代码如下:
import socket
host='192.168.137.101'
port=33333
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
while True:
msg=input("输入消息:")
s.sendto(msg.encode(),(host,port))
if msg =='bye':
break
data,addr=s.recvfrom(1024)
print(f"收到回复:{data.decode()}")
s.close()

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。
更多推荐
所有评论(0)