Python—網絡編程Socket

網絡編程Socket

Socket是應用層與TCP/IP協議族通信的中間軟件抽象層,它是一組接口。在設計模式中,Socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在Socket接口後面,對用戶來說,一組簡單的接口就是全部,讓Socket去組織數據,以符合指定的協議。

所以開發人員無需深入理解tcp/udp協議,socket已經爲我們封裝好了,我們只需要遵循socket的規定去編程,寫出的程序自然就是遵循tcp/udp標準的。

Python—網絡編程Socket

1.UDP套接字

  udp服務端:

1 ss = socket() #創建一個服務器的套接字
2 ss.bind() #綁定服務器套接字
3 inf_loop: #服務器無限循環
4cs = ss.recvfrom()/ss.sendto() # 對話(接收與發送)
5 ss.close() # 關閉服務器套接字
  udp客戶端:

1 cs = socket() # 創建客戶套接字
2 comm_loop: # 通訊循環
3 cs.sendto()/cs.recvfrom() # 對話(發送/接收)
4 cs.close() # 關閉客戶套接字
2.recv與recvfrom的區別:

part1:

發消息都是將數據發送到己端發送緩衝中,收消息都是從己端的緩衝區中收

tcp:send發消息,recv收消息

udp:sendto發消息,recvfrom收消息

part2:

tcp是基於數據流的,而udp是基於數據報的

send(bytes_data):發送數據流,數據流bytes_data若爲空,自己這段的緩衝區也爲空,操作系統不會控制tcp協議發空包

sendinto(bytes_data,ip_port):發送數據報,bytes_data爲空,還有ip_port,所有即便是發送空的butes_data,數據報其實也不是空的,自己這端的緩衝區收到內容,操作系統就會控制udp協議發包.

part3:

1.tcp協議:

(1)如果收消息緩衝區裏的數據爲空,那麼recv就會阻塞(阻塞很簡單,就是一直在等着接收)

(2)只不過tcp協議的客戶端send一個空數據就是真的空數據,客戶端即使有無窮個send空,也跟沒有一個樣.

(3)tcp基於鏈接通信

 *基於鏈接,則需要listen(backlog),指定半連接池的大小

 *基於鏈接,必須先運行的服務端,然後客戶端發起鏈接請求

 *對於Mac空系統:如果一段斷開了鏈接,那另外一端的鏈接也跟着完蛋recv將不會阻塞,收到的是空(解決方法是:服務端在收消息後加上if判斷,空消息就break掉通信循環)

 *對於Windows/Linux系統:如果一端斷開了鏈接,那另外一端的鏈接也跟着完蛋recv將不會阻塞,收到的是空(解決方法:服務端通信循環內加異常處理,捕捉到異常後就break掉通訊循環)

2.udp協議

(1)如果收消息緩衝區裏的數據爲"空",recvfrom也會阻塞

(2)支部會udp協議的客戶端sendinto一個空數據並不是真的空數據(包含:空數據+地址信息,得到的報仍然不會爲空),所以客戶端只要有一個sendinto(不管是否發送空數據,都不會真的空數據),服務端就可以recvfrom到數據.

(3)udp無鏈接

*無鏈接,因而無需listen(backlog),更加沒有什麼連接池之說了

*無鏈接,udp的sendinto不用管是否有一個正在運行的服務端,可以己端一個勁的發消息,只不過數據丟失

*recvfrom收的數據小於sendinto發送的數據時,在Mac和Linux系統上數據直接丟失,在Windows系統上發送的比接受的大直接報錯

*只有sendinto發送數據沒有recvfrom收數據,數據丟失

  PS:

    1.你單獨運行上面的udp的客戶端,你發現並不會報錯,相反tcp卻會報錯,因爲udp協議只負責把包發出去,對方收不收,我根本管不着,而tcp是基於鏈接的,必須有一個服務端先運行着,客戶端去跟服務端建立連接然後依託於連接才能傳遞消息,任何一方試圖把連接摧毀都會導致對方程序崩潰

    2.上面的udp程序,你註釋任何一條客戶端的sendinto,服務端都會卡住,爲什麼?因爲服務端有幾個recvfrom就要對應幾個sendinto,哪怕是sendinto(b'')那也要有.

3.粘包現象:

  只有TCP有粘包現象,UDP永遠不會粘包!

  所謂的粘包問題主要還是因爲接收對方不知道消息之間的界限,不知道一次性提取多少字節的數據造成的.

  以下情況會發生粘包:

  1.發送端需要等緩衝區滿才發送出去,造成粘包(發送數據時間間隔很短,數據量很小,會合到一起,產生粘包)

  2.接收方不及時接收緩衝區的包,造成多個包接收(客戶端發送一端數據,服務端只收了一小部分,服務端下次再收的時候還是從緩衝區拿上次遺留的數據,產生粘包)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章