會將數據量比較小的而且時間間隔比較短的數據
一次性打包發送給對方什麼是粘包python
上次或者前面的數據沒發收完,致使以後的影響了以後的獲取數據這種現象shell
將數據量比較小的而且時間間隔比較短的數據json
一次性打包發送給對方,對方沒接收完緩存
3.1服務端socket
import socket, subprocess server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(('127.0.0.1', 8000)) server.listen(5) while True: conn, addr = server.accept() print('start...') while True: cmd = conn.recv(1024) print('cmd:', cmd) obj = subprocess.Popen(cmd.decode('utf8'), shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) stdout = obj.stdout.read() if stdout: ret = stdout else: stderr = obj.stderr.read() ret = stderr ret_len = len(ret) conn.send(str(ret_len).encode('utf8')) data = conn.recv(1024).decode('utf8') if data == 'recv_ready': conn.sendall(ret) conn.close() server.close()
3.2客戶端code
import socket client = socket.socket() # 拿電話 client.connect(('127.0.0.1',8080)) # 撥號 寫的是對方的ip和port client.send(str(1).encode("utf-8")) # client.send(b'hello') # client.send(b'world') # client.send(b'baby')
直入主題,最好的解決方法:使用struct模塊建立報頭server
解決粘包問題的核心就是:爲字節流加上自定義固定長度報頭,報頭中包含字節流長度,而後一次send到對端,對端在接收時,先從緩存中取出定長的報頭,而後再取真實數據。索引
解決粘包問題
服務端
1.先製做一個發送給客戶端的字典
2.製做字典的報頭
3.發送字典的報頭
4.發送字典
5.再發真實數據ip客戶端
1.先接受字典的報頭
2.解析拿到字典的數據長度
3.接受字典
4.從字典中獲取真實數據的長度
5.接受真實數據utf-8
import socket import subprocess import struct import json server = socket.socket() server.bind(('127.0.0.1',8080)) server.listen(5) while True: conn, addr = server.accept() while True: try: cmd = conn.recv(1024) if len(cmd) == 0:break cmd = cmd.decode('utf-8') obj = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) res = obj.stdout.read() + obj.stderr.read() d = {'name':'jason','file_size':len(res),'info':'asdhjkshasdad'} json_d = json.dumps(d) # 1.先製做一個字典的報頭 header = struct.pack('i',len(json_d)) print(type(header), header ,'12345678') # 2.發送字典報頭 conn.send(header) # 3.發送字典 conn.send(json_d.encode('utf-8')) # 4.再發真實數據 conn.send(res) # conn.send(obj.stdout.read()) # conn.send(obj.stderr.read()) except ConnectionResetError: break conn.close()
import socket import struct import json client = socket.socket() client.connect(('127.0.0.1',8080)) while True: msg = input('>>>:').encode('utf-8') if len(msg) == 0:continue client.send(msg) # 1.先接受字典報頭 header_dict = client.recv(4) # 2.解析報頭 獲取字典的長度 dict_size = struct.unpack('i',header_dict)[0] # 解包的時候必定要加上索引0 # 3.接收字典數據 dict_bytes = client.recv(dict_size) dict_json = json.loads(dict_bytes.decode('utf-8')) # 4.從字典中獲取信息 print(dict_json) recv_size = 0 real_data = b'' while recv_size < dict_json.get('file_size'): # real_size = 102400 data = client.recv(1024) real_data += data recv_size += len(data) print(real_data.decode('gbk')) """ 1.如何將對方發送的數據收乾淨 """