套接字及其方法



套接字是雙向通訊通道的端點。它們可以在一個程序內、同一臺機器上的程序之間或不同機器上的程序之間進行通訊。類似地,網路套接字是在計算機網路(例如網際網路)上執行的兩個程式之間通訊流中的一個端點。它純粹是一個虛擬事物,並不代表任何硬體。網路套接字可以透過IP地址和埠號的唯一組合來標識。網路套接字可以基於多種不同的通道型別實現,例如TCP、UDP等等。

網路程式設計中使用的與套接字相關的不同術語如下:

域是指用作傳輸機制的協議族。這些值是常量,例如AF_INET、PF_INET、PF_UNIX、PF_X25等等。

型別

型別表示兩個端點之間的通訊型別,通常對於面向連線的協議為SOCK_STREAM,對於無連線的協議為SOCK_DGRAM。

協議

這可以用來標識域和型別內協議的變體。其預設值為0。這通常被忽略。

主機名

這作為網路介面的識別符號。主機名可以是字串、點分四元組地址或冒號(可能還有點)表示法的IPV6地址。

每個伺服器監聽一個或多個埠上的客戶端呼叫。埠可以是Fixnum埠號、包含埠號的字串或服務的名稱。

Python的Socket模組用於套接字程式設計

要在Python中實現套接字程式設計,我們需要使用Socket模組。以下是建立套接字的簡單語法:

import socket
s = socket.socket (socket_family, socket_type, protocol = 0)

在這裡,我們需要匯入socket庫,然後建立一個簡單的套接字。以下是建立套接字時使用的不同引數:

  • **socket_family** - 如前所述,這是AF_UNIX或AF_INET。

  • **socket_type** - 這是SOCK_STREAM或SOCK_DGRAM。

  • **protocol** - 這通常被忽略,預設為0。

套接字方法

在本節中,我們將學習不同的套接字方法。下面描述了三組不同的套接字方法:

  • 伺服器套接字方法
  • 客戶端套接字方法
  • 通用套接字方法

伺服器套接字方法

在客戶端-伺服器架構中,有一個集中的伺服器提供服務,許多客戶端從該集中式伺服器接收服務。客戶端也向伺服器發出請求。此架構中一些重要的伺服器套接字方法如下:

  • **socket.bind()** - 此方法將地址(主機名、埠號)繫結到套接字。

  • **socket.listen()** - 此方法基本上監聽與套接字建立的連線。它啟動TCP監聽器。Backlog是此方法的引數,它指定排隊連線的最大數量。其最小值為0,最大值為5。

  • **socket.accept()** - 這將接受TCP客戶端連線。對(conn, address)是此方法的返回值對。這裡,conn是一個新的套接字物件,用於在連線上傳送和接收資料,而address是繫結到套接字的地址。在使用此方法之前,必須使用socket.bind()和socket.listen()方法。

客戶端套接字方法

在客戶端-伺服器架構中,客戶端請求伺服器並從伺服器接收服務。為此,只有一個專用於客戶端的方法:

  • **socket.connect(address)** - 此方法主動啟動伺服器連線,或者簡單地說,此方法將客戶端連線到伺服器。引數address表示伺服器的地址。

通用套接字方法

除了客戶端和伺服器套接字方法之外,還有一些通用套接字方法在套接字程式設計中非常有用。通用套接字方法如下:

  • **socket.recv(bufsize)** - 顧名思義,此方法從套接字接收TCP訊息。引數bufsize代表緩衝區大小,定義此方法在任何時候可以接收的最大資料量。

  • **socket.send(bytes)** - 此方法用於向連線到遠端機器的套接字傳送資料。引數bytes將給出傳送到套接字的位元組數。

  • **socket.recvfrom(data, address)** - 此方法從套接字接收資料。此方法返回兩對(data, address)值。Data定義接收到的資料,address指定傳送資料的套接字的地址。

  • **socket.sendto(data, address)** - 顧名思義,此方法用於從套接字傳送資料。此方法返回兩對(data, address)值。Data定義傳送的位元組數,address指定遠端機器的地址。

  • **socket.close()** - 此方法將關閉套接字。

  • **socket.gethostname()** - 此方法將返回主機的名稱。

  • **socket.sendall(data)** - 此方法將所有資料傳送到連線到遠端機器的套接字。它將不間斷地傳輸資料,直到發生錯誤,如果發生錯誤,則它使用socket.close()方法關閉套接字。

建立伺服器和客戶端之間連線的程式

要建立伺服器和客戶端之間的連線,我們需要編寫兩個不同的Python程式,一個用於伺服器,另一個用於客戶端。

伺服器端程式

在這個伺服器端套接字程式中,我們將使用**socket.bind()**方法將其繫結到特定的IP地址和埠,以便它可以監聽該IP和埠上的傳入請求。稍後,我們將使用**socket.listen()**方法將伺服器置於監聽模式。例如,作為**socket.listen()**方法引數的數字4意味著如果伺服器繁忙,則最多保持4個連線等待,如果第五個套接字嘗試連線,則連線將被拒絕。我們將使用**socket.send()**方法向客戶端傳送訊息。最後,我們將分別使用**socket.accept()**和**socket.close()**方法來啟動和關閉連線。以下是伺服器端程式:

import socket
def Main():
   host = socket.gethostname()
   port = 12345
   serversocket = socket.socket()
   serversocket.bind((host,port))
   serversocket.listen(1)
   print('socket is listening')
   
   while True:
      conn,addr = serversocket.accept()
      print("Got connection from %s" % str(addr))
      msg = 'Connecting Established'+ "\r\n"
      conn.send(msg.encode('ascii'))
      conn.close()
if __name__ == '__main__':
   Main()

客戶端程式

在客戶端套接字程式中,我們需要建立一個套接字物件。然後,我們將連線到伺服器正在執行的埠——在我們的示例中為12345。之後,我們將使用**socket.connect()**方法建立連線。然後,透過使用**socket.recv()**方法,客戶端將從伺服器接收訊息。最後,**socket.close()**方法將關閉客戶端。

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = socket.gethostname()
port = 12345

s.connect((host, port))
msg = s.recv(1024)

s.close()
print (msg.decode('ascii'))

現在,執行伺服器端程式後,我們將在終端上獲得以下輸出:

socket is listening
Got connection from ('192.168.43.75', 49904)

執行客戶端程式後,我們將在另一個終端上獲得以下輸出:

Connection Established

處理網路套接字異常

可以使用**try**和**except**兩個塊來處理網路套接字異常。以下是用於處理異常的Python指令碼:

import socket
host = "192.168.43.75"
port = 12345
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

try:
   s.bind((host,port))
   s.settimeout(3)
   data, addr = s.recvfrom(1024)
   print ("recevied from ",addr)
   print ("obtained ", data)
   s.close()
except socket.timeout :
   print ("No connection between client and server")
   s.close()

輸出

上述程式生成以下輸出:

No connection between client and server

在上述指令碼中,首先我們建立了一個套接字物件。接下來,我們提供了伺服器正在執行的主機IP地址和埠號——在我們的示例中為12345。稍後,使用try塊,並在其中使用**socket.bind()**方法,我們將嘗試繫結IP地址和埠。我們使用**socket.settimeout()**方法來設定客戶端的等待時間,在我們的示例中,我們設定了3秒。except塊用於在伺服器和客戶端之間未建立連線時列印訊息。

廣告