套接字詳解(socket)


用戶認為的信息之間傳輸只是建立以兩個應用程序上,實際上在TCP連接中是靠套接字來作為他們連接的橋梁。

那么什么是套接字呢?

TCP用主機的IP地址加上主機上的端口號作為TCP連接的端點,這種端點就叫做套接字(socket)或插口。套接字用(IP地址:端口號)表示,區分不同應用程序進程間的網絡通信和連接,主要有3個參數:通信的目的IP地址、使用的傳輸層協議(TCP或UDP)和使用的端口號

python中的套接字

python中引用套接字的模塊是socket,在服務端和客戶端間的信息傳輸中,套接字起到了決定性的作用,因其功能不同共分為三種套接字,一個是監聽套接字,在服務端負責一直監聽着客戶端是否有請求發來;一種是客戶端套接字,負責與服務端建立聯系並收發信息;最后一種是對等連接套接字,是在服務端和客戶端負責收發信息。

上圖中出現了雙工這個詞,那么什么是單工、半雙工、全雙工呢?

根據通信雙方的分工和信號傳輸方向可將通信分為三種方式:單工、半雙工與全雙工。單工數據傳輸只支持數據在一個方向上傳輸;在同一時間只有一方能接受或發送信息,不能實現雙向通信,舉例:電視,廣播。半雙工數據傳輸允許數據在兩個方向上傳輸,但是,在某一時刻,只允許數據在一個方向上傳輸,它實際上是一種切換方向的單工通信;在同一時間只可以有一方接受或發送信息,可以實現雙向通信。舉例:對講機。全雙工數據通信允許數據同時在兩個方向上傳輸,舉例:電話通信。

用代碼實現服務端與客戶端通信

服務端代碼如下:

import socket

server = socket.socket()
server.bind(('127.0.0.5',8520))
server.listen(5)
while True:
    a,b = server.accept()
    while True:
        date = a.recv(1024)
        if date:
            print("已收到信息-->{}".format(date.decode()))
            a.send(date)
        else:
            a.close()
            break;

客戶端代碼如下:

import socket
client = socket.socket()
client.connect(('127.0.0.5',8520))
mess = input('--->').encode()
client.send(mess)
print("已收到信息-->{}".format(client.recv(1024)))
client.close()

客戶端效果:

--->hello,world!
已收到回應-->b'hello,world!'

服務端效果:

已收到信息-->hello,world!

代碼詳解

服務端實現上述效果流程:

  1. 創建套接字,即實例化。server = socket.socket()
  2. 綁定地址,且地址是一個元組,里面包括ip和端口,為自己創建了一個地址,用於客戶端的連接。server.bind(('127.0.0.5',8520))
  3. 開始監聽,此時的套接字server才被真正叫做監聽套接字,自此之前,客戶端是無法連接過來的。代碼中的5表示最大能同時連接到客戶端的數量。server.listen(5)
  4. 收到連接請求就建立與客戶端連接,返回結果由兩個變量接收,第一個變量是對等連接套接字,第二個是客戶端的地址(ip和端口)a,b = server.accept(),這里要特別注意是會有阻塞現象,阻塞在下面介紹。
  5. 利用對等連接套接字開啟接收信息狀態。若接到空值,表示客戶端已主動斷開連接。這里也會產生一次阻塞,客戶端是無法發送空值的。代碼的1024表示可以接收的最大字節數。a.recv(1024)
  6. 信息傳遞講究一收一發,一發一收。若收到信息,應給客戶端一個回復。這里要注意的是信息的傳遞是以字節的形式。a.send(date)
  7. 若收到空值,最后一步是斷開連接。a.close()

客戶端實現上述效果流程:

  1. 創建套接字,即實例化生成客戶端套接字。client = socket.socket()
  2. 向服務端發送連接請求,連接成功后,原本的客戶端套接字實際上就變成了對等連接套接字。代碼中的ip和端口是服務端的ip和端口。client.connect(('127.0.0.5',8520))
  3. 向服務端發送信息。client.send(mess)
  4. 向服務端接收信息,這里會發生一次阻塞。client.recv(1024)
  5. 主動斷開與服務端的連接,這時客戶端會自動向服務端發送一個空值。client.close()

什么是阻塞?

最早我們見過的阻塞應該是input,但那時我們應該還沒有這方面的認識,阻塞是指當代碼運行的這里時,需要觸發到某個條件,代碼才能繼續運行下去,否則會一直堵在這。而最早見的input,我們只要輸入字符再按enter就可以繼續運行了。在套接字中我們碰到兩個阻塞,一個是accept,它的疏通條件是客戶端發送連接請求,還有一個是recv,它的疏通條件是接收的對方發來的信息。

代碼中各個對象解剖

實例化對象

綁定地址后

接受到連接請求后

客戶端連接成功后

套接字阻塞帶來的影響:因為阻塞導致服務端一次只能與一個客戶端相連,這在實際應用中是萬萬不可行的,在下篇博客中,我會對非阻塞套接字做一個總結。


免責聲明!

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



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