python全棧學習--day35(黏包機制)
阿新 • • 發佈:2018-05-07
class 網關 優化方法 OS 方法 xxx mission 多條 lose
黏包
粘包現象
同時執行多條命令之後,得到的結果很可能只有一部分,在執行其他命令的時候又接收到之前執行的另外一部分結果,這種顯現就是黏包。
基於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 socket BUFSIZE=1024 ip_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 struct import socket sk = 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 socket import struct sk = 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(黏包機制)