粘包處理,檔案傳輸

2022-08-11 04:30:13 字數 2592 閱讀 9590

粘包的概念

粘包:多個資料報被連續儲存於連續的快取中,在對資料報進行讀取時由於無法確定發生方的傳送邊界,而採用某一估

測值大小來進行資料讀出,若雙方的size不一致時就會使指傳送方傳送的若干包資料到接收方接收時粘成一包,從接收

緩衝區看,後一包資料的頭緊接著前一包資料的尾。

出現粘包的原因

出現粘包現象的原因是多方面的,它既可能由傳送方造成,也可能由接收方造成。

傳送方引起的粘包是由tcp協議本身造成的,tcp為提高傳輸效率,傳送方往往要收集到足夠多的資料後才傳送一包資料。若連續幾次傳送的資料都很少,通常tcp會根據優化演算法把這些資料合成一包後一次傳送出去,這樣接收方就收到了粘包資料。

接收方引起的粘包是由於接收方使用者程序不及時接收資料,從而導致粘包現象。這是因為接收方先把收到的資料放在系統接收緩衝區,使用者程序從該緩衝區取資料,若下一包資料到達時前一包資料尚未被使用者程序取走,則下一包資料放到系統接收緩衝區時就接到前一包資料之後,而使用者程序根據預先設定的緩衝區大小從系統接收緩衝區取資料,這樣就一次取到了多包資料

粘包的處理方式:

(1)當時短連線的情況下,不用考慮粘包的情況

(2)如果傳送資料無結構,如檔案傳輸,這樣傳送方只管傳送,接收方只管接收儲存就ok,也不用考慮粘包

(3)如果雙方建立長連線,需要在連線後一段時間內傳送不同結構資料

接收方建立預處理執行緒,對接收到的資料報進行預處理,將粘連的包分開;

分包是指在出現粘包的時候我們的接收方要進行分包處理。(在長連線中都會出現) 資料報的邊界發生錯位,導致讀出錯誤的資料分包,進而曲解原始資料含義。

粘包情況有兩種,一種是粘在一起的包都是完整的資料報,另一種情況是粘在一起的包有不完整的包。

示例傳送端

import

socket

import

struct

ser=socket.socket(socket.af_inet,socket.sock_stream)

ser.bind((

'127.0.0.1

',10086))

ser.listen(5)

import

subprocess

while

true:

com,adr=ser.accept()

while

true:

try:

msg=com.recv(2048)

ifnot

msg:

com.close()

break

cmd=msg.decode('

utf-8')

print('

傳入命令%s

'%cmd)

s= subprocess.popen(cmd,stderr=subprocess.pipe,

stdout=subprocess.pipe,shell=true)

return_info=s.stdout.read()

return_err=s.stderr.read()

hander_size=len(return_info)+len(return_err)#使用struct 將真實資料的長度轉為固定的位元組資料

print

(hander_size)

hander_bytes=struct.pack('i'

,hander_size)

com.send(hander_bytes)#傳送長度資料

com.send(return_err)#傳送真實資料

com.send(return_info)

except

exception as a:

print

(a) com.close()

break

接收端

import

socket

client=socket.socket(socket.af_inet,socket.sock_stream)

client.connect((

'127.0.0.1

',10086))

import

struct

while

true:

cmd=input('

請輸入命令

').strip()

ifnot

cmd:

continue

if cmd=='q'

:

break

client.send(cmd.encode(

'utf-8'))

hander=client.recv(4)          #先收長度資料 位元組數固定

info_size=struct.unpack('i'

,hander)[0]

print('

接收到資料程度為%s

'%info_size)

info=client.recv(info_size)    #再收真實資料 真實可能很長 需要迴圈接收

print(info.decode('

gbk'

))client.close()

傳送端和接收端必須都處理粘包 才算真正的解決了

socket大檔案傳輸(解決粘包)

解決粘包 模組struct struct.pack type,num type 是num的型別 num 是乙個數字 r struct.pack 把乙個數字打包成乙個四位元組的bytes struct.unpack type,r 功能 解包,把r解成原數字,結果是乙個元組,原數字在元組的下標位0的位置...

處理TCP網路傳輸「粘包」疑難

在應用開發過程中,筆者發現基於tcp網路傳輸的應用程式有時會出現粘包現象 即傳送方傳送的若干包資料到接收方接收時粘成一包 針對這種情況,我們進行了專題研究與實驗。本文重點分析了tcp網路粘包問題,並結合實驗結果提出了解決該問題的對策和方法,供有關工程技術人員參考。一 tcp協議簡介 tcp是乙個面向...

VC檔案傳輸

vc 檔案傳輸的實現 2008 07 20 20 33 要實現檔案傳輸最簡單的辦法是寫兩個執行緒,乙個伺服器段的傳送處理執行緒,乙個客戶端的接收處理執行緒。執行緒處理函式需要宣告為類的靜態成員,由於不可訪問類內部的資料成員,所以引數傳遞裡面最好有個類的指標 伺服器段的傳送處理執行緒 cfiletra...