9月26日學習內容整理 TCP協議的粘包現象

2022-05-11 16:28:41 字數 1802 閱讀 5043

一:粘包現象的由來

tcp俗稱流式協議,源源不斷的傳送資料

但是tcp協議有個特點,就是會把間隔時間很短並且資料量較小的一些資料合為乙個大資料進行傳送

這個特點對於傳送端來說,如果連續傳送幾個資料量很小的資料流,那麼tcp就會將它們合為乙個大資料,接收端收到這個大資料就會不知道怎麼解析,分不清資料的分布,這樣就會出錯。這就是傳送端的粘包現象

對於接受端來說,即使傳送端沒有發生粘包現象,當傳送端送來準確的資料流時,接受端並沒有全盤接受,而是設定了接受數量的上限或者由於檔案過大無法一次接受完或者接收端並不知道檔案的大小,這時候剩下來的資料就會暫時存在記憶體中,可是當傳送端再送來資料時就會滯留在之前遺留資料的後等待接受,這時接收端想要接受後面的資料是取不出來的,這就是接收端的粘包現象,原因就是接收端對資料大小的未知

重要重要重要::::粘包現象的根源在於接收端一方對資料流的大小長度分布都不明確,導致無法處理粘包資料

補充:1、subprocess模組:用於執行系統命令

obj  =   subprocess . popen(系統命令(必須是字串形式),shell = true , stdout=subprocess . pipe , stdin =subprocess . pipe , stderr = subprocess . pipe )

shell代表是呼叫當前系統命令直譯器

stdout 代表標準準確輸出,pipe表示乙個管道,是想命令結果存到這樣乙個管道裡,而不是列印到螢幕上

stdin  代表標準輸入,也是將輸入的內容存到管道裡

stderr  代表標準錯誤輸出,是將命令輸入錯誤時顯示的結果存在管道裡,而不是直接列印到螢幕上

obj . stdout.read()   將正確的命令結果從管道中取出來,輸出的是位元組型別

obj . stderr.read()    將錯誤的命令結果從管道裡取出來,輸出的是位元組型別

注意因為是執行的系統命令,所以結果肯定是以當前系統預設的編碼儲存的,所以要想轉化為字串,就必須以相應的系統編碼轉換

二、對粘包的處理

1、思路:

(1)第一種思路:傳送端傳送資料前先傳送當前資料的長度以供接受端分辨

(2)第二種思路:若能將資料的長度封裝在資料的固定長度包頭裡,這樣資料端先接受包頭的固定長度,再迴圈接受具體的資料內容,再依據接受到的的長度對資料長度進行判斷就可以接受完整的資料流了

(3)第三種思路(最終的解決辦法):因為資料的長度有大有小,非常大的資料長度可能無法包裝在固定的資料頭部裡,並且資料頭部也不一定只有長度資訊,所以這時就想到把資料頭部寫成字典型別,在序列化成字串,再轉為位元組型別,這個位元組長度應該不會特別特別大,這樣長度問題就解決了。然後將這個位元組長度包裝在固定長度的資料頭部中,傳送時先傳送這個固定長度的資料頭(接收端就知道位元組的長度了),再傳送位元組資料(這時接收端就按照之前接受的長度接受),最後傳送具體資料。這樣接受端就完整的接受到了這個位元組型別,再轉換為字串,再反序列化為字典,就得到資料頭部的具體內容,在從中提取資料長度或者其它資訊,再按照資料長度迴圈接受就得到完整準確的資料了

2、思路實現:

第一種思路弊端太大,不採用

第二種和第三種思路合起來。就要用到  struct   模組

struct模組

(1)打包:obj = struct . pack(' i ' , 數字)  i就代表是整型格式,把這個數字轉為位元組型別並固定在4個位元組

(2)解包: struct . unpack(' i ' , obj) 也要指定整型格式,把打包好的obj物件解析出來,輸出的是元組 (45,)類似這樣,45就代表被打包的數字,通常後面加上索引0 [0] 取到這個被打包的數字

(3)格式為整型時,數字的範圍是有限制的,所以引出了第三種思路

10月26日學習內容整理 pymysql模組

一 pymysql模組 其實就是提供了socket客戶端和mysql服務端的通訊介面 1 發起連線 conn pymysql.connect host 127.0.0.1 也就是服務端位址 port 3306,埠號就是3306 user root 使用者名稱 password 使用者名稱對應的密碼 ...

9月26日培訓日記

作業 編寫乙個程式,用 show d 庫名 顯示出庫中的所有表,用 show t 表名 顯示出乙個表中的各個字段資訊,用 show i 表明 顯示出乙個表中的各個欄位名及相應的各行資料。課堂上隨手寫的一段示意 resultset rs resultsetmetadata r d rs.getmeta...

9月26日培訓日記

作業 編寫乙個程式,用 show d 庫名 顯示出庫中的所有表,用 show t 表名 顯示出乙個表中的各個字段資訊,用 show i 表明 顯示出乙個表中的各個欄位名及相應的各行資料。課堂上隨手寫的一段示意 resultset rs resultsetmetadata rsmd rs.getmet...