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

2022-05-06 01:51:09 字數 2743 閱讀 5458

解決粘包

模組struct

struct.pack(type,num)

type:是num的型別

num :是乙個數字

r =struct.pack 把乙個數字打包成乙個四位元組的bytes

struct.unpack(type,r)

功能:解包,把r解成原數字,結果是乙個元組,原數字在元組的下標位0的位置

#解決粘包:原理是在伺服器接收到字典長度後,根據字典長度去recv字典中的內容,就不會造成recv最後一次接收完後剩下的空間留給部分檔案內容所造成字典內容和檔案內容黏在一起

#實現檔案的上傳功能

#client層

import

socket

import

json

import

struct

import

ossk=socket.socket()

sk.connect((

"10.70.2.143

",8080))

option=

for index,value in

option.items():

print

(index,value)

num=input("

請輸入您的選擇")

if num=="1"

: dic=

file_path=input("

請輸入所需要上傳的檔案的絕對路徑")

filename=os.path.basename(file_path)

filesize=os.path.getsize(file_path)

dic[

"filename

"]=filename

dic[

"filesize

"]=filesize

#將字典轉為字串型別

str_dic=json.dumps(dic)

#獲取字典的長度,為了解決粘包

len_dic=len(str_dic)

#解決粘包:原理是在伺服器接收到字典長度後,根據字典長度去recv字典中的內容,就不會造成recv最後一次接收完後剩下的空間留給部分檔案內容所造成字典內容和檔案內容黏在一起

#用乙個4bytes的資料表示字典的長度

#伺服器接收的時候先接收recv(4)個位元組長度就可以得到字典的長度

b_len_dic=struct.pack('

i',len_dic) #

i是原字典長度的資料型別,第二個引數是需要轉化的那個字典長度本身

#將bytes型別的字典長度和字典內容進行拼接並且傳送

sk.send(b_len_dic+str_dic.encode("

utf-8

")) #

此時字典內容是bytes型別所以可以進行bytes的拼接

#檔案的上傳

with open(file_path,"rb"

) as f:

#根據檔案大小進行檔案的上傳

while

filesize:

content=f.read(1024)

sk.send(content)

filesize-=len(content)

else

:

pass

sk.close()

#server層

import

socket

import

json

import

struct

sk=socket.socket()

sk.bind((

"10.70.2.143

",8080))

sk.listen()

conn,addr=sk.accept()

#先接收從客戶端傳過來的四個位元組長度的字典長度

b_len_dic=conn.recv(4)

#將位元組長度的字典長度進行解包成整型的字典長度

len_dic=struct.unpack('

i',b_len_dic)[0] #

因為字典長度傳過來的是乙個元組的第0個下標元素

#根據字典長度去接收字典的內容

#下次進行檔案傳輸的時候就不會造成粘包現象

str_dic=conn.recv(len_dic).decode("

utf-8")

#將字串的字典反序列化成字典

dic=json.loads(str_dic)

if dic["

opt"]=="

upload":

#為了防止檔案同名,使用字串拼接檔名進行區分

filename="

1"+dic["

filename"]

#接收從客戶端傳過來的檔案

with open(filename,"ab"

) as f:

#根據檔案大小接收資料

while dic["

filesize"]:

content=conn.recv(1024)

f.write(content)

#字典中檔案大小減去已接受的檔案大小

dic["

filesize

"]-=len(content)

elif dic["

opt"]=="

download":

pass

conn.close()

sk.close()

粘包處理,檔案傳輸

粘包的概念 粘包 多個資料報被連續儲存於連續的快取中,在對資料報進行讀取時由於無法確定發生方的傳送邊界,而採用某一估 測值大小來進行資料讀出,若雙方的size不一致時就會使指傳送方傳送的若干包資料到接收方接收時粘成一包,從接收 緩衝區看,後一包資料的頭緊接著前一包資料的尾。出現粘包的原因 出現粘包現...

socket檔案傳輸

伺服器 本檔案是伺服器的 include for sockaddr in include for socket include for socket include for printf include for exit include for bzero include for time t an...

socket檔案傳輸

最近入職培訓中需要寫乙個linux下的c s網路檔案傳輸工具,在實現的過程中,遇到了一些坑,在這裡 做個總結 由於udp伺服器不需要accept 因此也沒有link id 連線的客戶端id 在伺服器檔案接收或下發檔案時需要知道當下與之通訊的客戶端的識別符號,由於udp是無連線的,並且sockfd s...