解決客戶端與服務端傳輸資料黏包問題

2021-09-24 18:57:06 字數 2839 閱讀 3332

方案21.因為傳送資料報時,每次傳送的包小,因為系統進行優化演算法,就將兩次的包放在一起傳送,減少了資源的重複占用。多次傳送會經歷多次網路延遲,一起傳送會減少網路延遲的次數。因此在傳送小資料時會將兩次資料一起傳送,而客戶端接收時,則會一併接收。#即出現多次send會出現黏包

2.是因為接收資料時,又多次接收,第一次接收的資料量小,導致資料還沒接收完,就停下了,剩餘的資料會快取在記憶體中,然後等到下次接收時和下一波資料一起接收。

將報頭內容組成結構體,發給服務端;報頭:報頭標識"package"+報文長度len

傳送完報頭,緊接著傳送長度為len的報文(json串形式)發給服務端;

struct pkg_header_t

;int64 clientsocket::senddata(qstring qmsg)

iret = client->write(q);

if (-1 == iret)

return iret;

}

接收報頭結構體,校驗報頭標識"package",獲取報文長度len

根據報頭資訊緊接著迴圈接收,直到接收長度為len的報文(json串);

sk =socket.socket()#建立乙個socket物件

sk.bind(('127.0.0.1',8080))#繫結本地ip位址與埠

sk.listen()#開啟監聽

buffer =1024 #設定buffer值大小

conn,addr =sk.accept()#等待客戶端連線服務端,得到位址與雙共工通道

head_len=conn.recv(4)#接收用struck將數字轉長度為4的bytes

head_len =struct.unpack('i',head_len)[0]#呼叫struct模組來解包,得到原來的數字(數字為報頭的長度)

json_head =conn.recv(head_len).decode('utf-8')#接收json序列化的報頭進行解碼

head =json.loads(json_head)#將json序列化的報頭進行反序列化

filesize =head['filesize']#拿到head字典中鍵filesize所對應的值

print(filesize)#列印filesize

with open(r'dir\%s'%head['filename'],'wb')as f:#dir\檔名,拿到檔案的路徑,以wb模式開啟

while filesize:#當filesize(檔案內剩餘內容的大小)有值時

if filesize >=buffer:#如果filesize>= buffer值,buffer值是設定的一次接收多少位元組的內容

print(filesize) #列印filesize大小

content =conn.recv(buffer)#接收buffer值大小的內容

f.write(content)#寫入檔案

filesize -=buffer#原來的檔案大小減去接收的內容,等於剩餘檔案的大小

else:#如果檔案剩餘的內容大小',len(content))

print(filesize)

print('伺服器端')

conn.close()

sk.close()

import struct

import os

import json

import socket

sk =socket.socket

sk.connect(('127.0.0.1',8090))

buffer =1024

head =#定義乙個報頭

file_path =os.path.join(head['filepath'],head['filename'])#將檔名與檔案路徑載入進目錄中

filesize = os.path.getsize(file_path)#得到目錄中檔案的大小

head['filesize'] =filesize#將檔案大小賦值回列表中

json_head =json.dumps(head)#將head字典序列化

bytes_head =json_head.encode('utf-8')#將序列化之後的字典進行解碼

head_len =len(bytes_head)#計算轉碼之後字典的長度

pack_len =struct.pack('i',head_len)#呼叫struct模組將長度轉換成長度為4的bytes型別

sk.send(pack_len)#傳送pack_len

sk.send(bytes_head)#傳送bytes_head

with open(file_path,'rb')as f:

while filesize:

print(filesize)

if filesize>=buffer:

content =f.read(buffer)

print('====>',len(content))

sk.send(content)

filesize-=buffer

else:

content =f.read(filesize)

sk.send(content)

filesize=0

sk.close()

**:

服務端向客戶端傳輸檔案

23.1 閱讀須知 所以如果不符合你的需求就不用往下了。這是用socket傳輸檔案的服務端 include sockaddr in include socket include socket include printf include exit include bzero define serve...

客戶端與服務端資料加密傳輸方案

總結從前一篇網路安全基礎要點知識介紹中可以知道,在網路通訊中,通訊傳輸資料容易被擷取或篡改,如果在傳輸使用者隱私資料過程中,被不法分子擷取或篡改,就可能導致使用者受到傷害,比如被詐騙,所以對客戶端與服務端的傳輸資料加密,是網路通訊中必不可少的。首先,客戶端與服務端商量好資料加密協議,對傳輸資料做到安...

TCP 服務端 客戶端 傳輸資料結構

編寫4個檔案 server.c client.c sum.h makefile 主要是客戶端 與服務端在傳輸資料的時候,不是直接傳遞字串,而是傳遞自定義的資料結構 注意 tcp傳送的資訊是以位元組為單位保證順序的.當兩台機器都同時小端機或大端機時,傳輸是正常的。否則,可能會出現異常情況。server...