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