粘包问题
tcp协议才会有粘包问题,udp协议没有粘包问题.
因为tcp协议是将需要传输的内容先读入缓存里,然后在一点点传,受接收方字符限制,并不能一次传输完成,第二次就会将第一次剩下的部分+第二次的内容传输
而udp协议,是如果接收方一次性没有接收完全,剩下数据将被丢弃.
粘包问题的几种情况
- 两个数据非常小,间隔时间又短
- 数据太大,一次取不完,下一次还会取这个大数据
解决粘包问题
在传数据之前,传一个数据的大小,数据的大小必须得定长
基于udp协议的socket套接字编程
udp无需连接
- 服务端
import socketserver = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)server.bind(('127.0.0.1', 8000))print('start...')while True: data, client_addr = server.recvfrom(1024) print(client_addr) print(data) server.sendto(data.upper(), client_addr)
- 客户端
import socketclient = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)while True: msg = input('please enter your msg:') client.sendto(msg.encode('utf8'), ('127.0.0.1', 8000)) data = client.recvfrom(1024) print(data)
基于socketserver实现并发的socket套接字编程
让服务端同时和多个客户端进行连接交互
- 服务端
# 同一时刻有多个人在接听import socketserverimport subprocessimport structclass MyHandler(socketserver.BaseRequestHandler): # 通信循环 def handle(self): while True: try: cmd = self.request.recv(1024) print(cmd) pipeline = subprocess.Popen(cmd.decode('utf8'), shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) stdout = pipeline.stdout.read() stderr = pipeline.stderr.read() count_len = len(stdout) + len(stderr) guding_bytes = struct.pack('i', count_len) self.request.send(guding_bytes) # 4 self.request.send(stderr + stdout) except ConnectionResetError: break# 使用socketserver的连接循环(并发),但是使用了自己的通信循环# myhandler = MyHandler()if __name__ == '__main__': server = socketserver.ThreadingTCPServer(('127.0.0.1', 8000), MyHandler, bind_and_activate=True) print('start...') server.serve_forever()