標籤:接收 匯入 back 通訊 就是 tcp 緩衝區 系統 資料流
基於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#建立socketskt = 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#建立socketskt = 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()
Python學習之——Socket通訊端(UDP串連)