Python基础学习(28)TCP协议的Python实现 UDP协议的Python实现 黏包 利用struct模块解决黏包
一、今日内容
- TCP(Transport Control Protocol) 协议的 Python 实现
- UDP(User Datagram Protocol) 协议的 Python 实现
- 输出变色字体
- 黏包
- 利用 struct 模块解决黏包
二、TCP 协议的 Python 实现
-
基本形式
# server.py import socket sk = socket.socket() sk.bind(('192.168.1.100', 9000)) # 申请操作系统端口资源 sk.listen() print('sk:', sk) # sk: <socket.socket fd=456, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('192.168.1.100', 9000)> conn, addr = sk.accept() # conn存储的是一个客户端和server端的连接信息 print('conn:', conn) # conn: <socket.socket fd=460, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('192.168.1.100', 9000), raddr=('192.168.1.100', 53673)> conn.send(b'hello') msg = conn.recv(1024) print(msg) conn.close() # 挥手 断开连接 sk.close() # 归还申请的操作系统资源
# client.py import socket sk = socket.socket() sk.connect(('192.168.1.100', 9000)) msg = sk.recv(1024) print(msg) sk.send(b'byebye') sk.close()
-
多次对话
# server.py import socket sk = socket.socket() sk.bind(('192.168.1.100', 9000)) # 申请操作系统端口资源 sk.listen() while True: conn, addr = sk.accept() # conn存储的是一个客户端和server端的连接信息 print('conn:', conn) # 每次运行客户端发现不是一个端口 # raddr=('192.168.1.100', 53830) # raddr=('192.168.1.100', 53831) # raddr=('192.168.1.100', 53832) # raddr=('192.168.1.100', 53833) # .... while True: send_msg = input('>>>') conn.send(send_msg.encode('utf-8')) if send_msg.upper() == 'Q': break msg = conn.recv(1024).decode('utf-8') if msg.upper() == 'Q': break print(msg) conn.close() # 挥手 断开连接 sk.close() # 归还申请的操作系统资源
# client.py import socket sk = socket.socket() sk.connect(('192.168.1.100', 9000)) while True: msg = sk.recv(1024).decode('utf-8') if msg.upper() == 'Q': break print(msg) send_msg = input('>>>') sk.send(send_msg.encode('utf-8')) if send_msg.upper() == 'Q': break sk.close()
三、UDP 协议的 Python 实现
# server.py
import socket
sk = socket.socket(type=socket.SOCK_DGRAM) # UDP协议
# socket.socket(type=socket.SOCK_STREAM) # TCP协议(默认)
sk.bind(('127.0.0.1', 9000))
# 非全双工通信,服务端不可以先发送消息
# sk.recv(1024) # 不可以使用recv,因为这样无法获知发送端
while True:
msg, addr = sk.recvfrom(1024)
print(msg.decode('utf-8'))
s_msg = input('>>>')
sk.sendto(s_msg.encode('utf-8'), addr)
# client.py
import socket
sk = socket.socket(type=socket.SOCK_DGRAM)
server = ('127.0.0.1', 9000)
while True:
s_msg = input('>>>')
sk.sendto(s_msg.encode('utf-8'), server)
msg = sk.recv(1024).decode('utf-8') # 地址已知,不用recvfrom
if msg.upper() == 'Q': # 服务端发送q退出发送的客户端,只需要单方面推出
break
print(msg)
四、输出变色字体
当日常在使用print()
等内置打印函数时,统一的字体颜色和背景让我们在打印结果较多时比较难以分辨,这时可以在打印的字符串前加上一小段字符实现变色等功能:
- 将