粘包算法
1.什麼是粘包:shell
粘包就是接收方不知道消息的界限,從而使發過來的多個消息/數據粘連在一塊兒的現象json
2.爲何會形成粘包:socket
粘包的狀況有兩種:優化
①發送端因爲nagle優化算法的緣由,會將數據時間間隔很短、數據很小的消息/數據匯合到一塊兒之後再進行發送,產生粘包;spa
②接受方不及時接收緩衝區的包,形成多個包接收(發送方發送了一段數據,但接收方只收了一小部分,下次發送方再次發送時,接收方會優先拿到上次沒有接收完的數據,形成粘包)code
3.怎麼解決粘包問題server
事例:blog
服務端:ip
import socket import json import struct import subprocess server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(('127.0.0.1', 8083)) server.listen(5) while True: conn, client_addr = server.accept() while True: try: cmd = conn.recv(1024) if len(cmd) == 0: break obj = subprocess.Popen( cmd.decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) stdout = obj.stdout.read() stderr = obj.stderr.read() header_dic = { 'file_name': '返回文本', 'file_size': len(stderr) + len(stdout), 'md5': 'asgddasgdadag' } header_str = json.dumps(header_dic) header_bytes = header_str.encode('utf-8') conn.send(struct.pack('i', len(header_bytes))) conn.send(header_bytes) conn.send(stdout) conn.send(stderr) except Exception: break conn.close()
客戶端:
import socket import json import struct client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) client.connect(('127.0.0.1',8083)) while True: cmd = input('>>:').strip() if len(cmd) == 0:continue client.send(cmd.encode('utf-8')) header_size = client.recv(4) header_bytes = client.recv(struct.unpack('i',header_size)[0]) header_str = header_bytes.decode('utf-8') header_dic = json.loads(header_str) file_size = header_dic['file_size'] recv_size = 0 res = b'' while recv_size < file_size: data = client.recv(1024) recv_size += len(data) res += data print(res.decode('gbk'))