日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

学习笔记(11):Python网络编程并发编程-粘包底层原理分析

發(fā)布時(shí)間:2023/12/10 python 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 学习笔记(11):Python网络编程并发编程-粘包底层原理分析 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

立即學(xué)習(xí):https://edu.csdn.net/course/play/24458/296241?utm_source=blogtoedu

?1.send和recv底層分析

?

?

1)不管是recv還是send都不是直接接收對(duì)方數(shù)據(jù)或者發(fā)送給對(duì)方數(shù)據(jù),而是對(duì)自己的操作系統(tǒng)內(nèi)存進(jìn)行操作;

?

2)客戶端與服務(wù)端并不是一個(gè)send對(duì)于一個(gè)recv;

?

3)send過(guò)程分析(此處以客戶端向服務(wù)端發(fā)送數(shù)據(jù)為例):

?

???? #1.客戶端將數(shù)據(jù)發(fā)送給自己的操作系統(tǒng),即將數(shù)據(jù)給操作系統(tǒng)內(nèi)存,這樣就算是結(jié)束了send這個(gè)命令,而至于怎么將數(shù)據(jù)發(fā)送給服務(wù)端由客戶端的操作系統(tǒng)決定;

?

???? #2.send需要經(jīng)歷的階段:產(chǎn)生數(shù)據(jù)——將數(shù)據(jù)copy給客戶端自己的操作系統(tǒng)內(nèi)存

?

4)recv過(guò)程分析(以服務(wù)端接收客戶端數(shù)據(jù)為例)

?

??? #1.服務(wù)端首先是等待客戶端的數(shù)據(jù),然后接收數(shù)據(jù)即可

?

??? #2.recv經(jīng)歷的階段:wait data(耗時(shí)較長(zhǎng))——copy data(首先是客戶端的操作系統(tǒng)內(nèi)存的數(shù)據(jù)通過(guò)網(wǎng)關(guān)發(fā)送給服務(wù)端的操作系統(tǒng)內(nèi)存,然后再由服務(wù)端的程序從自身的操作系統(tǒng)內(nèi)存中copy data,再進(jìn)行執(zhí)行,這就完成recv的過(guò)程)

?

2.粘包產(chǎn)生的原因:由TCP協(xié)議中的優(yōu)化算法nagle算法決定的。TCP協(xié)議存在的問(wèn)題,在UDP協(xié)議中不會(huì)出現(xiàn)這種問(wèn)題

?

1)產(chǎn)生粘包的條件:數(shù)據(jù)小且兩次或多次發(fā)送數(shù)據(jù)的間隔小的情況下會(huì)產(chǎn)生粘包現(xiàn)象,所以使用TCP協(xié)議不是一定會(huì)發(fā)生粘包,只有滿足條件才會(huì)

?

2)在TCP協(xié)議中,send是一條一條消息地發(fā)送數(shù)據(jù),而recv卻可以一次性接收多條消息發(fā)送的數(shù)據(jù),即接收到的數(shù)據(jù)是一個(gè)整體,因?yàn)樵跁r(shí)間間隔較短的時(shí)間內(nèi)發(fā)送的小數(shù)據(jù)會(huì)在客戶端的操作系統(tǒng)內(nèi)存中會(huì)被合并成一個(gè)數(shù)據(jù)包,再發(fā)送給服務(wù)端的操作系統(tǒng)內(nèi)存,因此無(wú)法判斷出哪些數(shù)據(jù)是哪條消息的,TCP時(shí)面向流的

?

?

?

?3)TCP是面向流的,為了減少IO傳輸

的次數(shù)進(jìn)而增加傳輸數(shù)據(jù)的效率,采用了nagle算法,將間隔時(shí)間短的小數(shù)據(jù)合并成一個(gè)大的數(shù)據(jù)塊進(jìn)行接收處理,然后將處理后的大的數(shù)據(jù)塊返回給客戶端,而客戶端無(wú)法識(shí)別出哪些數(shù)據(jù)是哪條信息的,故產(chǎn)生了粘包!

?

?

4)在客戶端粘包的情況,在客戶端時(shí)間間隔短的情況下發(fā)送兩次數(shù)據(jù),導(dǎo)致客戶端發(fā)送的數(shù)據(jù)產(chǎn)生粘包現(xiàn)象

#客戶端產(chǎn)生粘包的情況''' 客戶端 ''' import socket phone = socket.socket((socket.AF_INET,socket.SOCK_STREAM)) phone.connect(('127.0.0.1',8080)) phone.send('hello') phone.send('world')''' 服務(wù)端 ''' import socket phone = socket.socket((socket.AF_INET,socket.SOCK_STREAM)) phone.bind(('127.0.0.1',8080)) conn,client = phone.accept()res1 = conn.recv(1024) #b'helloworld' print('第一次接收的數(shù)據(jù):',res1)res2 = phone.recv(1024) #b'' print('第二次接收的數(shù)據(jù):',res2)#客戶端不存在粘包的現(xiàn)象,只需要在客戶端的兩次send之間加入一個(gè)time.sleep(2)即可,即破壞粘包產(chǎn)生的條件之一:間隔時(shí)間短的情況下發(fā)送多次數(shù)據(jù)

?

4)服務(wù)端產(chǎn)生粘包現(xiàn)象

#客戶端 ...... phone.send('hello'.encode('utf-8')) time.sleep(5) phone.send('world'.encode('utf-8')) ......#服務(wù)端 ...... res1 = conn.recv(1) #b'h' print('第一次接收的數(shù)據(jù)',res1) time.sleep(6)#服務(wù)器端比客戶端多睡一秒鐘,因此上一次的發(fā)送的未接收的數(shù)據(jù)‘ello’會(huì)和這次發(fā)送的world在服務(wù)器端的操作系統(tǒng)內(nèi)存中合并在一起 res2 = conn.recv(1024) #b'elloworld' print('第二次接收的數(shù)據(jù):',res2)

注:上述只是便于理解才用time.sleep()來(lái)解決粘包,實(shí)際上是非常不支持這樣來(lái)解決粘包問(wèn)題

總結(jié)

以上是生活随笔為你收集整理的学习笔记(11):Python网络编程并发编程-粘包底层原理分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。