一.缓冲区
二.两种黏包现象
两种黏包现象:
1 连续的小包可能会被优化算法给组合到一起进行发送
黏包现象1客户端
1 import socket 2 BUFSIZE = 1024 3 ip_prort = ('127.0.0.1',8001) 4 5 s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 6 7 res = s.connect(ip_prort) 8 9 s.send('hi'.encode('utf-8')) 10 s.send('meinv'.encode('utf-8'))
黏包现象1服务端
1 from socket import * 2 ip_prot = ('127.0.0.1',8001) 3 4 tcp_socket_server = socket(AF_INET,SOCK_STREAM) 5 6 tcp_socket_server.bind(ip_prot) 7 8 tcp_socket_server.listen(5) 9 10 conn,addr = tcp_socket_server.accept() 11 12 data1 = conn.recv(10) 13 data2 = conn.recv(10) 14 15 print('->>>>>',data1.decode('utf-8')) 16 print('->>>>>',data2.decode('utf-8')) 17 18 conn.close()
2 第一次如果发送的数据大小2000B接收端一次性接受大小为1024,这就导致剩下的内容会被下一次recv接收到,导致结果错乱
黏包现象2客户端
1 import socket 2 3 client = socket.socket() 4 5 ip_prot ='127.0.0.1',8002 6 7 client.connect(ip_prot) 8 9 while 1: 10 cmd = input('请输入指令') 11 12 client.send(cmd.encode('utf-8')) 13 14 server_cmd_result = client.recv(1025) 15 16 print(server_cmd_result.decode('GBK'))
黏包现象2服务端
1 import socket 2 import subprocess 3 4 server = socket.socket() 5 6 ip_prot = '127.0.0.1', 8002 7 8 server.bind(ip_prot) 9 10 server.listen() 11 12 conn, addr = server.accept() 13 14 while 1: 15 from_client_cmd = conn.recv(1024) 16 17 print(from_client_cmd.decode('utf-8')) 18 19 sub_obj = subprocess.Popen( 20 from_client_cmd.decode('utf-8'), # 传入的cmd命令 21 shell=True, 22 stdout=subprocess.PIPE, # 正确结果的存放位置 23 stderr=subprocess.PIPE # 错误结果的存放位置 24 ) 25 26 std_msg = sub_obj.stdout.read() # 获得管道里面拿到结果 27 28 print('指令的执行结果长度>>>>', len(std_msg)) 29 30 conn.send(std_msg)
三.黏包解决方案
客户端
1 import socket 2 import struct 3 4 client = socket.socket() 5 ip_port = '127.0.0.1',8001 6 7 client.connect(ip_port) 8 9 while 1: 10 cmd = input('请输入指令') 11 12 # 发送指令 13 14 client.send(cmd.encode('utf-8')) 15 16 server_res_len = client.recv(4) 17 18 msg_len = struct.unpack('i',server_res_len)[0] 19 20 print('来自服务器端的消息长度',msg_len) 21 22 server_cmd_result = client.recv(msg_len) 23 24 print(server_cmd_result.decode('GBK'))
服务端
1 import socket 2 import subprocess 3 import struct 4 5 server = socket.socket() 6 ip_port = '127.0.0.1',8001 7 8 server.bind(ip_port) 9 10 server.listen() 11 12 conn,addr = server.accept() 13 14 while 1: 15 from_client_cmd = conn.recv(1024) 16 17 print(from_client_cmd.decode('utf-8')) 18 19 sub_obj = subprocess.Popen( 20 21 from_client_cmd.decode('utf-8'), 22 shell = True, 23 stdout=subprocess.PIPE, 24 stderr=subprocess.PIPE 25 ) 26 27 std_msg = sub_obj.stdout.read() 28 29 std_msg_len = len(std_msg) 30 31 print('指令的执行结果长度>>>>',std_msg_len) 32 33 msg_lenint_struct = struct.pack('i',std_msg_len) 34 35 conn.send(msg_lenint_struct + std_msg)