Python學習之——Socket套接字(UDP連接)


基於UDP的socket

面向無連接的不可靠數據傳輸,可以沒有服務器端,只不過沒有服務器端,發送的數據會被直接丟棄,並不能到達服務器端

 

由於UDP是面向無連接的(實際上有鏈接,不然通過什么去傳數據去取數據),可以使用多個客戶端連接服務端,但這並不是並發訪問。

注意:

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

   tcp:send發消息,recv收消息

   udp:sendto發消息,recvfrom收消息

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

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

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

3.1 tcp協議

(1)如果收消息緩沖區里的數據為空,那么recv就會阻塞(阻塞很簡單,就是一直在等着收)

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

(3)tcp基於鏈接通信

  • 基於鏈接,則需要listen(backlog),指定半連接池的大小
  • 基於鏈接,必須先運行的服務端,然后客戶端發起鏈接請求
  • 對於mac系統:如果一端斷開了鏈接,那另外一端的鏈接也跟着完蛋recv將不會阻塞,收到的是空(解決方法是:服務端在收消息后加上if判斷,空消息就break掉通信循環)
  • 對於windows/linux系統:如果一端斷開了鏈接,那另外一端的鏈接也跟着完蛋recv將不會阻塞,收到的是空(解決方法是:服務端通信循環內加異常處理,捕捉到異常后就break掉通訊循環)

3.2 udp協議

(1)如果如果收消息緩沖區里的數據為“空”,recvfrom也會阻塞

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

(3)udp無鏈接

  • 無鏈接,因而無需listen(backlog),更加沒有什么連接池之說了
  • 無鏈接,udp的sendinto不用管是否有一個正在運行的服務端,可以己端一個勁的發消息,只不過數據丟失
  • recvfrom收的數據小於sendinto發送的數據時,在mac和linux系統上數據直接丟失,在windows系統上發送的比接收的大直接報錯
  • 只有sendinto發送數據沒有recvfrom收數據,數據丟失

 

實現代碼

服務端:

#導入socket模塊
import socket
#創建socket
skt = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#綁定地址和端口
skt.bind(('127.0.0.1',9090))
#循環
while True:
    #調用接受消息
    data,addr = skt.recvfrom(1024)
    #接受成功回復消息
    rst = b'I am fine'
    skt.sendto(rst,addr)
    print('server Done')
    #關閉鏈接
    skt.close()

客戶端

#導入模塊
import socket
#創建socket
skt  = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#創建發送消息和發送目標
msg = b'Hello world'
addr = ('127.0.0.1',9090)
skt.sendto(msg,addr)
#接受回復
rst = skt.recvfrom(1024)
print(rst)
print('client done')
#關閉鏈接
skt.close()

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM