Python網絡編程,粘包、分包問題的解決
阿新 • • 發佈:2018-03-26
tde 網絡 ons scope time mib struct imp multicast
tcp編程中的粘包、分包問題的解決:
參考:https://blog.csdn.net/yannanxiu/article/details/52096465
服務端:
#!/bin/env python # -*- coding:utf-8 -*- import socket import time import struct import json import socket import sys class SockPackBody(): def __init__(self , data_buffer = bytes() , header_size = 4): self.data_buffer = data_buffer self.header_size = header_size self.header = None self.body_size = 0 self.body = None def PackBody(self , sock): while True: ‘‘‘一次接收循環‘‘‘ recv_pkg = sock.recv(1024) if not recv_pkg and len(self.data_buffer) == 0 : ‘‘‘connect closed , and no data in buffer.‘‘‘ return None self.data_buffer += recv_pkg if len(self.data_buffer) < self.header_size: ‘‘‘接收到的數據包小於self.headerSize,說明連包頭都沒接受完整‘‘‘ continue self.header = struct.unpack("!1I" , self.data_buffer[:self.header_size]) self.body_size = self.header[0] #分包 if len(self.data_buffer) < self.header_size + self.body_size: ‘‘‘接收到的數據包小於self.header_size + self.body_size,說明整個數據包都沒接受完整‘‘‘ continue self.body = self.data_buffer[self.header_size:self.header_size + self.body_size] #粘包 self.data_buffer = self.data_buffer[self.header_size + self.body_size:] return self.body if __name__ == ‘__main__‘: sock_pkger = SockPackBody() sock = socket.socket(socket.AF_INET , socket.SOCK_STREAM) sock.bind((‘0.0.0.0‘ , 6688)) sock.listen(5) agent_sock , agent_addr = sock.accept() n = 1 while True: ‘‘‘一次連接(會話)循環‘‘‘ recv_data = sock_pkger.PackBody(agent_sock) if not recv_data: agent_sock.close() break print recv_data
客戶端:
import socket import time import struct import json import sys reload(sys) sys.setdefaultencoding(‘utf-8‘) serve_host = "localhost" server_port = 6688 class PkgBuildHeader(object): def __init__(self, body_size ,): self.pack_header = struct.pack("!1I", body_size) if __name__ == ‘__main__‘: client = socket.socket() client.connect(serve_host , server_port) # 正常數據包定義 body = ‘‘‘Link encap:Ethernet HWaddr 00:0C:29:EF:84:A3 inet addr:192.168.31.140 Bcast:192.168.31.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:feef:84a3/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:236844 errors:0 dropped:0 overruns:0 frame:0 TX packets:233949 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:107658740 (102.6 MiB) TX bytes:41874253 (39.9 MiB) ‘‘‘ header = PkgBuildHeader(len(body)) sendData1 = header.pack_header + body.encode() # 分包數據定義 header = PkgBuildHeader(len(body)) sendData2_1 = header.pack_header+body[:20].encode() sendData2_2 = body[20:].encode() # 粘包數據定義 body1 = "Link encap:Ethernet HWaddr 00:0C:29:EF:84:A3" header1 = PkgBuildHeader(len(body1)) body2 = "RX bytes:107658740 (102.6 MiB) TX bytes:41874253 (39.9 MiB)" header2 = PkgBuildHeader(len(body2)) sendData3 = header1.pack_header+body1.encode()+header2.pack_header+body2.encode() # 正常數據包 client.send(sendData1) time.sleep(30) # 分包測試 client.send(sendData2_1) time.sleep(1) client.send(sendData2_2) time.sleep(3) # 粘包測試 client.send(sendData3) time.sleep(3) client.close()
Python網絡編程,粘包、分包問題的解決