网络编程之黏包
服务端:
import socket import subprocess import struct import logging logger = logging.basicConfig(filename='粘包.txt', format='%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s', level=30) import traceback #创建scoket对象 server = socket.socket() #绑定ip,端口 server.bind(('127.0.0.1',8000)) server.listen(5) while 1: print('等待连接') conn,addr = server.accept() while 1: try: print('等待接受命令') cmd = conn.recv(1024) print('接受命令',cmd) #远程执行命令 res = subprocess.Popen(cmd.decode('utf-8'),shell=True, stdin= subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) #从管道读出来都是字节,只能读一次 err = res.stderr.read() out = res.stdout.read() if err: #创建报头,在一定范围内4字节 ret = struct.pack('i',len(err)) #发送包头 conn.send(ret) #发送数据 conn.send(err) elif not out: conn.send('命令没有返回值'.encode('utf8')) else: res =struct.pack('i',len(out)) conn.send(res) conn.send(out) print('发送成功') except Exception as e: print(e) break
客户端:
import socket import struct import subprocess client = socket.socket() client.connect(('127.0.0.1',8000)) while 1: cmd = input('>>>') if cmd == 'exit':break elif not cmd:continue else: #发送cmd命令 client.send(cmd.encode('utf-8')) print('发送成功') #接收报头长度,在struct模块打包长度4字节 data_length = client.recv(4) #解报头长度 data_length = struct.unpack('i',data_length)[0] print(data_length) recv_data = b"" recv_data_length =0 while recv_data_length < data_length : #接受报文 info_data = client.recv(1024) #拼接报文 recv_data += info_data #计算长度 recv_data_length += len(info_data) print(recv_data.decode('GBK'),recv_data_length)
3.struct模块 将数字打包到固定四字节
import struct ret = struct.pack('i',11112) #打包后四字节长度 print(ret,type(ret)) ret = struct.unpack('i',ret)[0] #解包返回的是元祖 print(ret,type(ret))

浙公网安备 33010602011771号