標籤:解決 資料 SM pack ufs 最大數 用戶端 接收 image
黏包
粘包現象
同時執行多條命令之後,得到的結果很可能只有一部分,在執行其他命令的時候又接收到之前執行的另外一部分結果,這種顯現就是黏包。
基於tcp協議實現的粘包
server 端
######server 端from socket import *ip_port=(‘127.0.0.1‘,8080)tcp_socket_server=socket(AF_INET,SOCK_STREAM)tcp_socket_server.bind(ip_port)tcp_socket_server.listen(5)conn,addr=tcp_socket_server.accept()data1=conn.recv(2)data2=conn.recv(10)print(‘----->‘,data1.decode(‘utf-8‘))print(‘----->‘,data2.decode(‘utf-8‘))conn.close()tcp_socket_server.close()
client 端
##########client
#_*_coding:utf-8_*_import socketBUFSIZE=1024ip_port=(‘127.0.0.1‘,8080)s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)res=s.connect_ex(ip_port)s.send(‘hello‘.encode(‘utf-8‘))s.send(‘egg‘.encode(‘utf-8‘))s.close()
執行輸出:
說明:中就是黏包的效應
原理
黏包現象的成因
#你不知道在哪兒斷句
解決辦法:
在發送資料的時候,先告訴對方要發送的大小就可以了
在發送的時候,先發送資料的大小 在發送內容
在接收的時候,先接受大小,在根據大小接收內容
自動協議
# ret = struct.pack(‘i‘,1920000)
# print(ret)
#
# ret = struct.unpack(‘i‘,ret)
# print(ret[0])
# 能夠把範圍內一個任意的整數轉換成一個固定長度的位元組
# 還能轉換回來
# 發送資料的時候
# xxxxtttttttttttttttttttttttttttttt
# 自訂了一個協議
import structimport socketsk = socket.socket()sk.bind((‘127.0.0.1‘,9000))sk.listen()conn,addr = sk.accept()while True: ret = conn.recv(4) length = struct.unpack(‘i‘,ret)[0] msg = conn.recv(length) print(msg.decode(‘utf-8‘))conn.close()
import socketimport structsk = socket.socket()sk.connect((‘127.0.0.1‘,9000))while True: msg = ‘hello world‘ length = struct.pack(‘i‘,len(msg)) sk.send(length) sk.send(msg.encode(‘utf-8‘))sk.close()
黏包成因TCP協議中的資料傳遞tcp協議的拆包機制
當發送端緩衝區的長度大於網卡的MTU時,tcp會將這次發送的資料拆成幾個資料包發送出去。 MTU是Maximum Transmission Unit的縮寫。意思是網路上傳送的最大資料包。MTU的單位是位元組。 大部分網路裝置的MTU都是1500。如果原生MTU比網關的MTU大,大的資料包就會被拆開來傳送,這樣會產生很多資料包片段,增加丟包率,降低網路速度。
面向流的通訊特點和Nagle演算法
TCP(transport control protocol,傳輸控制通訊協定)是連線導向的,面向流的,提供高可靠性服務。收發兩端(用戶端和伺服器端)都要有一一成對的socket,因此,發送端為了將多個發往接收端的包,更有效發到對方,使用了最佳化方法(Nagle演算法),將多次間隔較小且資料量小的資料,合并成一個大的資料區塊,然後進行封包。這樣,接收端,就難於分辨出來了,必須提供科學的拆包機制。 即面向流的通訊是無訊息保護邊界的。 對於空訊息:tcp是基於資料流的,於是收發的訊息不可為空,這就需要在用戶端和服務端都添加空訊息的處理機制,防止程式卡住,而udp是基於資料報的,即便是你輸入的是空內容(直接斷行符號),也可以被發送,udp協議會幫你封裝上訊息頭髮送過去。 可靠黏包的tcp協議:tcp的協議資料不會丟,沒有收完包,下次接收,會繼續上次繼續接收,己端總是在收到ack時才會清除緩衝區內容。資料是可靠的,但是會粘包。
python全棧學習--day35(黏包機制)