Python中的底層網路介面(套接字)
Python 標準庫中的 'socket' 模組定義了伺服器和客戶端機器如何使用作業系統上的套接字端點進行通訊。'socket' API 包含用於面向連線和無連線網路協議的函式。
套接字是雙向通訊鏈路的一個端點。它由 IP 地址和埠號來表徵。在任一端正確配置套接字對於啟動連線至關重要。這使得在客戶端-伺服器環境中監聽傳入訊息併發送響應成為可能。
'socket' 模組中的 socket() 函式設定套接字物件。
import socket obj = socket.socket(family, type, protocol)
'family' 引數預設為 AF_INET。其他可接受的值包括:AF_INET6、AF_UNIX、AF_CAN 或 AF_RDS。'type' 引數的值預設為 'SOCK_STREAM',表示面向連線的協議(TCP)。對於無連線協議(UDP),將其設定為 'SOCK_DGRAM'。'protocol' 引數通常預設為 0。
伺服器和客戶端上的套接字物件分別稱為伺服器套接字和客戶端套接字。套接字物件實現了以下方法
bind() | 此方法將套接字繫結到指定的 IP 地址和埠號。 |
listen() | 此方法啟動伺服器並進入監聽迴圈,等待來自客戶端的連線請求。 |
accept() | 當伺服器攔截連線請求時,此方法接受它並使用其地址識別客戶端套接字。 |
典型的伺服器端程式碼如下
import socket ss = socket.socket() ss.bind(('localhost',12345)) ss.listen() client, addr = ss.accept() print ("connection request from: " + str(addr))
如果本地機器用作伺服器以監聽來自同一機器作為客戶端的傳入訊息,則其 IP 地址為 '127.0.0.1',也稱為環回地址。它由主機名 'localhost' 識別。套接字被設定為監聽任意空閒埠號。對於網路中遠端機器之間的通訊,必須使用實際的 IP 地址。
客戶端套接字向其 IP 地址和埠號處監聽的伺服器套接字傳送連線請求
connect()
obj = socket.socket() obj.connect((host,port))
一旦伺服器接受了來自客戶端的連線請求,這兩個套接字物件現在就使用 TCP 協議連線,並且它們可以傳送和/或接收資料。
send()
伺服器使用它已攔截的地址向客戶端傳送資料。
client.send(bytes)
客戶端套接字向其已建立連線的套接字傳送資料。
obj.send(bytes)
sendall()
類似於 send()。此方法持續傳送資料,直到所有資料都發送完畢。
sendto()
此方法僅在 UDP 協議的情況下使用。
recv()
此方法用於檢索傳送到客戶端的資料。在伺服器的情況下,它使用已接受請求的遠端套接字。
client.recv(bytes)
在客戶端的情況下,
obj.recv(bytes)
recvfrom()
此方法在 UDP 協議的情況下使用。
伺服器程式碼
import socket host = "127.0.0.1" port = 12345 ss = socket.socket() ss.bind((host,port)) ss.listen() cs, addr = server.accept() print ("Connection from: " + str(addr)) while True: data = cs.recv(1024).decode() if not data: break print ("from connected user: " + str(data)) print ("Received from User: " + str(data)) data = input("type message: ") conn.send(data.encode()) cs.close()
客戶端程式碼
import socket host = '127.0.0.1' port = 12345 obj = socket.socket() obj.connect((host,port)) message = input("type message: ") while message != 'q': obj.send(message.encode()) data = obj.recv(1024).decode() print ('Received from server: ' + data) message = input("type message: ") obj.close()
開啟兩個命令提示符視窗。在一個視窗中先執行伺服器程式碼。在另一個視窗中執行客戶端程式碼。