socket之tcp、udp
Socket:套接字
一、Socket是在應用層與TCP\IP協議族通信的中間軟件抽象層,它把傳輸層與網絡層復雜的操作抽象為幾個簡單的接口共應用層調用已實現進程在網絡中的通信。
二、套接字:源IP地址和源端口號以及目標IP地址和目的端口號的組合稱為套接字。是支持TCP/IP的網絡通信的基本操作單元,可以看做是不同主機之間的進程進行雙向通信的端點,簡單的說就是通信的兩方的一種約定,用套接字中的相關函數來完成通信過程。
有人將socket說成是ip+port(端口號),ip標識網絡中的主機,port標識主機上的應用程序
二、Socket分為兩種:基於文件型的(AF_UNIX)、基於網絡型的(
基於網絡型(AF_INET)又分為兩種:tcp、udp(不需要手動建立連接)
三、Socket基於網絡型的TCP協議工作流程圖:
先從服務端說起:
1.先初始化:socket>>>>>>>>>soc=socket.socket() 調用模塊中的類產生套接字對象,
可以添加參數(三個參數:家族、類型,0),默認為基於網絡型的
2.與端口綁定:bind(元組) 參數為(ip,端口)
3.對端口進行監聽:listen()
4.調用阻塞,等待客戶端連接: accept()
2.客戶端的地址(ip和服務器相同,端口號不同,元組的形式)
5.用新的套接字進行操作數據:1.recv(1024) 參數1024表示每次從緩沖區讀取的數據 的長度
2.send(‘要發送的數據’.encode(編碼方式))
客戶端:
初始化客戶端:socket.socket()
連接服務器:connect()
如果連接成功,此時客戶端就可以發送數據,服務端就可以接受請求並處理請求,然後 把回應數據發送給客戶端,客戶端讀取數據,最後關閉連接,一次交互結束。
四、socket模塊中的socket
參數控制選擇家族、模式等,默認為基於網絡型的、TCP(需要建立連接)的套接字
第一個參數:選擇是基於網絡型,還是基於文件型
第二個參數:選擇TCP模式(需要手動建立連接),還是UDP模式(不需要建立連接)
第三個參數:通常默認為0
五、套接字(是個對象,如下面的s)的常用方法:
解析關鍵:
1、client,addr=accept()用於接收客戶端的連接請求,且會阻塞。當客戶端出現connect並且地址一致時,連接成功並且執行後面的代碼。
返回值1表示生成一個新的套接字:並且必須用這個新的套接字去操作數據
返回值2客戶端的地址(包括客戶端ip與端口號,註意同一臺計算機上服務器與客戶 端的ip是相同的)
2、recv是從操作系統的緩沖區中讀取數據的,並且會阻塞,只有向另一端發送數據,recv 操作系統的從緩沖區讀到內容,下面的代碼才會被執行。
總結:
一、默認情況下:使用的是基於網絡的,且協議為TCP:
TCP是基於連接的,所以必須先啟動服務端再啟動客戶端,否則報錯。
且一次連接之後只能跟一個客戶端通信,別的服務端想實現通信必須先讓服務端與原客戶端斷開連接,這就用到了,循環的去接收連接。
- tcp基礎版
- tcp循環版(循環處理數據,循環接收連接)
循環接收客戶端連接
循環收發數據(看上面recv介紹的循環結束條件)
當存在循環發送、接受數據時,結束條件就是客戶端強行關閉,
客戶端強行關閉有兩種情況:
1.在linux系統中客戶端強行關閉,recv會接收到空消息。不會導致服務端報錯,所以判斷recv的值是否為空為結束條件。
2.而window下,客戶端強行關閉,recv不會接受空消息,而是直接報錯。所以需要捕捉異常。並且以捕捉到異常作為結束條件。(即放在except後break)
- tcp異常處理(window下,客戶端斷開連接,服務端接收數據recv這一步會報錯)
- 半連接池(防止半連接次數過多)
二、基於網絡的,UDP協議:(需要指明參數)
UDP套接字是無連接的,所以先啟用哪一端,都不會報錯。
由於UDP是無連接的,所以可以同時多個客戶端與服務端同時通信。
不需要手動建立連接:
服務端指定參數後,只需要綁定(bind)ip地址與端口號不需要監聽和接收連接請求
客戶端也需要指定參數,不需要connect手動連接,可直接操作數據。多個客戶端可 以共存,同時向服務端發送數據。註意客戶端發送數據時,要指明(ip,端口號),即 sendto(),參數出了要發送的數據,還要接上服務器的ip地址和端口號。
socket之tcp、udp