您好,登錄后才能下訂單哦!
本篇內容主要講解“Python數據傳輸黏包問題怎么解決”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Python數據傳輸黏包問題怎么解決”吧!
黏包:指數據與數據之間沒有明確的分界線,導致不能正確的讀取數據。
應用數據想要發送數據就必須將數據交給操作系統,而操作系統需要同時為所有的應用程序提供數據傳輸服務,就意味著不可能馬上將應用數據發送,就需要為程序提供一個緩沖區,用于臨時存放數據。
當發送數據很快,有兩條數據都在緩沖區時,操作系統可能將兩個數據發給接收方,數據之間沒有分界線,接收方會誤認為是一條數據。
UDP在收發數據時是基于數據包的,即一個包一個包的發送,包與包之間有明確的分界,到達對方緩沖區后也是獨立數據包。這種方式存在的問題:
①發送數據的長度每個操作系統會有不同的限制,數據超過限制則無法發送;
②接收方接收數據時,如果應用程序提供的緩存容量小于數據包的長度,則會造成數據的丟失,而緩沖區大小不可能無限大。
這意味著UDP不會出現黏包問題,但會丟失數據,不可靠。
TCP增加了一套校驗規則來保證數據的完整性,會將超過TCP包最大長度的數據拆分為多個TCP包,并在傳輸數據時為每一個TCP數據包指定一個順序號,接收方在收到TCP數據包后按照順序將數據包進行重組,重組后的數據全都是二進制數據,且每次收到的二進制數據之間沒有明顯的分界。基于這種工作機制,TCP在三種情況下發生黏包問題:
①當單個數據包較小時,接收方可能一次性讀取了多個包的數據;
②當整體數據較大時,接收方可能一次性僅讀取了一個包的一部分內容;
③另外TCP協議為提高效率,增加了一種優化機制,會將數據小且發送間隔短的數據合并發送,該機制也會導致發送方將兩個數據包粘在一起發送。
也就是說,TCP傳輸數據是可靠的,但是會黏包。
服務器端:
from socket import * server_socket = socket(AF_INET,SOCK_STREAM) server_socket.bind(('',8080)) server_socket.listen(5) new_socket,client_addr = server_socket.accept() data1 = new_socket.recv(1024) data2 = new_socket.recv(1024) print("收到的第一條數據:",data1) print("收到的第二條數據:",data2) new_socket.close() server_socket.close()
客戶端:
from socket import * client_socket = socket(AF_INET,SOCK_STREAM) client_socket.connect(('10.175.193.126',8080)) client_socket.send('hello'.encode('utf-8')) client_socket.send('word'.encode('utf-8')) client_socket.close()
服務器端接收到的數據:
由于客戶端兩條數據發送間隔太短且數據包太小,被服務器端誤認為是一條數據。
服務器端:
from socket import * import time server_socket = socket(AF_INET,SOCK_STREAM) server_socket.bind(('',8080)) server_socket.listen(5) new_socket,client_addr = server_socket.accept() print("連接成功!",client_addr) data1 = new_socket.recv(3) #每次只接收三個字節,接收不完整 time.sleep(6) print("收到的第一條數據:",data1) data2 = new_socket.recv(10) #接收第一次未接收的數據,若有空間,會繼續接收新數據 print("收到的第二條數據:",data2) new_socket.close() server_socket.close()
客戶端:
from socket import * #通過time模塊使客戶端發送多個數據包時,時間間隔變長 import time client_socket = socket(AF_INET,SOCK_STREAM) client_socket.connect(('10.175.193.126',8080)) client_socket.send('hello'.encode('utf-8')) time.sleep(5) #讓當前線程休眠5秒 client_socket.send('word'.encode('utf-8')) client_socket.close()
服務器端接收到的數據:
①服務器端出現黏包:接收方不知道消息之間的界限,不知道一個消息要提取多少字節的數據造成的;
②客戶端出現黏包:TCP在發送數據少且間隔時間短的數據包時,會將幾條合并一起發送。
到此,相信大家對“Python數據傳輸黏包問題怎么解決”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。