国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

python TCP Socket的粘包和分包的處理詳解

2020-02-22 23:12:14
字體:
供稿:網(wǎng)友

概述

在進行TCP Socket開發(fā)時,都需要處理數(shù)據(jù)包粘包和分包的情況。本文詳細講解解決該問題的步驟。使用的語言是Python。實際上解決該問題很簡單,在應用層下,定義一個協(xié)議:消息頭部+消息長度+消息正文即可。

那什么是粘包和分包呢?

關于分包和粘包

粘包:發(fā)送方發(fā)送兩個字符串”hello”+”world”,接收方卻一次性接收到了”helloworld”。

分包:發(fā)送方發(fā)送字符串”helloworld”,接收方卻接收到了兩個字符串”hello”和”world”。

雖然socket環(huán)境有以上問題,但是TCP傳輸數(shù)據(jù)能保證幾點:

順序不變。例如發(fā)送方發(fā)送hello,接收方也一定順序接收到hello,這個是TCP協(xié)議承諾的,因此這點成為我們解決分包、黏包問題的關鍵。 分割的包中間不會插入其他數(shù)據(jù)。

因此如果要使用socket通信,就一定要自己定義一份協(xié)議。目前最常用的協(xié)議標準是:消息頭部(包頭)+消息長度+消息正文

TCP為什么會分包

TCP是以段(Segment)為單位發(fā)送數(shù)據(jù)的,建立TCP鏈接后,有一個最大消息長度(MSS)。如果應用層數(shù)據(jù)包超過MSS,就會把應用層數(shù)據(jù)包拆分,分成兩個段來發(fā)送。這個時候接收端的應用層就要拼接這兩個TCP包,才能正確處理數(shù)據(jù)。

相關的,路由器有一個MTU( 最大傳輸單元),一般是1500字節(jié),除去IP頭部20字節(jié),留給TCP的就只有MTU-20字節(jié)。所以一般TCP的MSS為MTU-20=1460字節(jié)。

當應用層數(shù)據(jù)超過1460字節(jié)時,TCP會分多個數(shù)據(jù)包來發(fā)送。

擴展閱讀

TCP的RFC定義MSS的默認值是536,這是因為 RFC 791里說了任何一個IP設備都得最少接收576尺寸的大小(實際上來說576是撥號的網(wǎng)絡的MTU,而576減去IP頭的20個字節(jié)就是536)。
TCP為什么會粘包

有時候,TCP為了提高網(wǎng)絡的利用率,會使用一個叫做Nagle的算法。該算法是指,發(fā)送端即使有要發(fā)送的數(shù)據(jù),如果很少的話,會延遲發(fā)送。如果應用層給TCP傳送數(shù)據(jù)很快的話,就會把兩個應用層數(shù)據(jù)包“粘”在一起,TCP最后只發(fā)一個TCP數(shù)據(jù)包給接收端。

開發(fā)環(huán)境

Python版本:3.5.1 操作系統(tǒng):Windows 10 x64

消息頭部(包含消息長度)

消息頭部不一定只能是一個字節(jié)比如0xAA什么的,也可以包含協(xié)議版本號,指令等,當然也可以把消息長度合并到消息頭部里,唯一的要求是包頭長度要固定的,包體則可變長。下面是我自定義的一個包頭:

版本號(ver) 消息長度(bodySize) 指令(cmd)

版本號,消息長度,指令數(shù)據(jù)類型都是無符號32位整型變量,于是這個消息長度固定為4×3=12字節(jié)。在Python由于沒有類型定義,所以一般是使用struct模塊生成包頭。示例:

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 扬州市| 霞浦县| 苍梧县| 华安县| 文安县| 东丰县| 塔城市| 昌都县| 同德县| 龙游县| 汾西县| 株洲县| 山丹县| 茌平县| 中牟县| 上思县| 会昌县| 东台市| 台北县| 屯门区| 莆田市| 肃北| 南靖县| 柳州市| 纳雍县| 多伦县| 吉安县| 荥阳市| 揭西县| 田阳县| 盐源县| 如东县| 涟源市| 昆山市| 安阳县| 绩溪县| 西宁市| 报价| 陵水| 奈曼旗| 庄河市|