學習筆記(1) socket tcp,udp

2021-08-20 08:41:23 字數 1280 閱讀 8686

首先要清楚的幾點是

socket服務本質是乙個應用服務,屬於應用層。

資料之間的傳輸依靠的是底層的硬體,如網絡卡,位於物理層,傳輸的是位元組。

應用層要想獲得物理層的資料必須通過作業系統,當socket要傳輸或者接收網路資料,必須由作業系統中間排程,socket只是單純的搬運緩衝區的資料。

網路之間的資料傳輸依靠的是tcp/udp等協議,socket服務只是單純的搬運工,要將二者區別開看。

tcp的傳輸是位元組流,udp傳輸的是資料報,兩者在資料傳輸上的區別是udp已經定製好報頭,而這些報頭也扮演著分隔符的功能,而位元組流更像流水,沒有界限,所以會socket搬運的時候只是按照規定的長度搬運,不管這串資料之間是否關聯,這就造成了粘包,而在udp中,由於有報頭作為分隔符就明確的知道報與報的關係,不會造成相互傾佔。

send()與recv()沒有一一對應的關係,sendto()與recvfrom()由於有報頭所以存在一一對應關係,具體的是,如果有3個傳送,卻有4個接受,那麼程式會卡在第4個接受上。

socket.recv() 與socket.recvfrom() 面對傳送訊息為空時:

前者會被阻塞,後者會正常傳送(不過送的內容為空),為何?因為前面已經提到了,udp協議會為每一次傳送訊息定製報頭,雖然傳送訊息為空,但是加上了報頭資料,所以接收方的緩衝區依然會接收到資料,反觀前者傳送為空,緩衝區就一直為空,相當於沒有任何傳送,接收程式依然在等待。

客戶端異常斷開服務和正常socket.close()的區別

正常關閉會使得recv不再阻塞,會一直搬運緩衝區的資料,而緩衝區為空,所以搬運一直的是空(b''),可以用乙個if判斷解決。

if msg:   #如果為空

break

#跳出通訊的迴圈,不再搬運資料

如果是異常斷開(即程式異常斷開,socket例項沒有關閉),則服務端會報錯,解決辦法:

try:

'這裡寫正常時執行的**'

except exception as e:

print(e)

'這裡寫處理辦法'

#這樣服務端程式就不會因為報錯而斷開連線

為tcp協議定製報頭

有時候,傳送量遠遠大於一次接受的量(一般接受不超過8k位元組),而緩衝區也小於要傳送的資料量,一般對資料做拆分處理。

請轉至這裡

學習筆記1

struct test test int x void fun class test1 test1 int x void fun int main void test1 a 行1 a.fun 行2 test1 b 行3 b.fun 行4 test c 行5 c.fun 行6 test d 行7 d....

學習筆記1

1 字串原地逆序 使用臨時變數 void reverse string s 5 求平均值 避免溢位 int f int x,int y 6 楊氏矩陣 bool young int a m n int x return false 7 十進位制轉十六進製制 string decimaltohexade...

學習筆記1

第二單元 linux的基本操作 1.改變使用者的密碼 passwd命令 注 a.只有root使用者可以修改其他使用者的密碼。普通使用者只能修改自己的密碼,且密碼必須設定地較為複雜,否則修改不成功 b.若執行passwd命令時後面不加使用者名稱,表示的是修改當前使用者的密碼。2.系統使用者的分類 注 ...