文章目錄
- 1. 服務器端
- 1.1 socket.socket()
- 1.2 socket.bind()
- 1.3 socket.listen()
- 1.4 socket.accept()
- 1.5 socket.recv()
- 1.6 socket.send() 和 socket.sendall()
- 1.7 socket.close()
- 2. 客戶端
- 2.1 socket.socket()
- 2.2 socket.connect()
- 2.3 socket.send() 和 socket.sendall()
- 2.4 socket.recv()
- 2.5 socket.close()
- 2.6 UDP 客戶端方法的差異
這里主要是介紹一下Socket通訊中服務端和客戶端需要使用的方法及其說明
1. 服務器端
在 Python 網絡編程里,服務器端通常會使用 socket 模塊中的多個方法來實現網絡通信。
下面為你詳細介紹服務器端常用的方法及其用法。
1.1 socket.socket()
-
功能:創建一個套接字對象。套接字是網絡編程的基礎,它就像是一個通信的端點,通過它可以進行數的發送和接受
-
語法:
socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)
- 參數說明:
- family:指定地址族,常用的有 socket.AF_INET(表示 IPv4 地址)和 socket.AF_INET6(表示 IPv6 地址)。
- type:指定套接字類型,常用的有 socket.SOCK_STREAM(表示 TCP 套接字)和 socket.SOCK_DGRAM(表示 UDP 套接字)。
- proto:通常取默認值 0。
- fileno:通常取默認值 None。
示例
import socket# 創建一個TCP/IPv4套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1.2 socket.bind()
-
功能:將套接字綁定到指定的IP地址和端口號。這樣客戶端就可以通過這個地址和端口找到服務器。
-
語法:
socket.bind(address)
-
參數說明
- address:是一個元組,格式為 (host, port),其中 host 是 IP 地址,port 是端口號。
示例:
# 服務器地址和端口
server_address = ('localhost', 8888)
server_socket.bind(server_address)
1.3 socket.listen()
- 功能:讓套接字進入監聽狀態,開始等待客戶端的連接請求
- 語法:
socket.listen(backlog)
- 參數說明
- backlog:指定允許排隊等待處理的最大連接請求數量
示例
# 開始監聽,允許最多5個連接請求排隊等待
server_socket.listen(5)
print('服務器正在監聽端口 8888...')
1.4 socket.accept()
- 功能:接受客戶端的請求,并返回一個新的套接字對象和客戶端地址。新的套接字對象用于與客戶端進行數據通信。
- 語法:
conn, addr = socket.accept()
- 返回值說明:
- coon:是一個新的套接字對象,用于與客戶端進行數據收發。
- addr:是客戶端的地址信息,通常是一個元組(host,port)
示例
while True:# 接受客戶端連接connection, client_address = server_socket.accept()print(f'連接來自: {client_address}')
1.5 socket.recv()
- 功能:從客戶端接收數據
- 語法:
data = socket.recv(bufsize)
- 參數說明:
- bufsize:指定一次最多接收的字節數
示例
# 接收客戶端發送的數據
data = connection.recv(1024)
print(f'收到的數據: {data.decode()}')
1.6 socket.send() 和 socket.sendall()
-
功能:向客戶端發送數據。send方法嘗試發送數據,但可能不會發送完所有的數據;sendall方法會確保所有數據都被發送出去
-
語法:
# send方法
sent = socket.send(data)
# sendall方法
socket.sendall(data)
- 參數說明:
- data:要發送的數據,必須是字節類型
示例
# 發送響應給客戶端
message = '你好,客戶端!'
connection.sendall(message.encode())
1.7 socket.close()
- 功能:關閉套接字,釋放相關資源
- 語法:
socket.close()
示例
# 關閉連接
connection.close()
完整示例
以下是一個完整的 TCP 服務器端示例代碼,展示了上述方法的綜合使用:
import socket# 創建一個TCP/IPv4套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 服務器地址和端口
server_address = ('localhost', 8888)
server_socket.bind(server_address)# 開始監聽,允許最多5個連接請求排隊等待
server_socket.listen(5)
print('服務器正在監聽端口 8888...')while True:# 接受客戶端連接connection, client_address = server_socket.accept()try:print(f'連接來自: {client_address}')# 接收客戶端發送的數據data = connection.recv(1024)print(f'收到的數據: {data.decode()}')# 發送響應給客戶端message = '你好,客戶端!'connection.sendall(message.encode())finally:# 關閉連接connection.close()
通過上述方法的使用,可以實現一個簡單的 TCP 服務器端,處理客戶端的連接請求和數據通信。
如果使用 UDP 協議,部分方法會有所不同,例如不需要 listen 和 accept 方法,而是直接使用 recvfrom 和 sendto 方法進行數據的收發。
2. 客戶端
在 Python 網絡編程里,客戶端也會用到 socket 模塊中的多個方法來和服務器進行通信。
下面詳細介紹客戶端常用的方法及其用法。
2.1 socket.socket()
- 功能:創建一個套接字對象,這是網絡通信的基礎,客戶端借助它來發送和接收數據。
- 語法:
socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)
- 參數說明:
- family:指定地址族,常見的有 socket.AF_INET(代表 IPv4 地址)和 socket.AF_INET6(代表 IPv6 地址)。
- type:指定套接字類型,常用的是 socket.SOCK_STREAM(表示 TCP 套接字)和 socket.SOCK_DGRAM(表示 UDP 套接字)。
- proto:一般取默認值 0。
- fileno:通常取默認值 None。
示例
import socket# 創建一個TCP/IPv4套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2.2 socket.connect()
- 功能:客戶端使用此方法向服務器發起連接請求。若服務器接受請求,雙方就會建立起連接。
- 語法:
socket.connect(address)
- 參數說明
- address:是一個元組,格式為 (host, port),host 是服務器的 IP 地址,port 是服務器監聽的端口號
示例
# 服務器地址和端口
server_address = ('localhost', 8888)
client_socket.connect(server_address)
2.3 socket.send() 和 socket.sendall()
- 功能:向服務器發送數據。send 方法嘗試發送數據,但也許不會發送完所有數據;sendall 方法會保證所有數據都被發送出去。
- 語法:
# send方法
sent = socket.send(data)
# sendall方法
socket.sendall(data)
- 參數說明
- data:要發送的數據,必須是字節類型。
示例
# 發送數據給服務器
message = '你好,服務器!'
client_socket.sendall(message.encode())
2.4 socket.recv()
- 功能:從服務器接收數據。
- 語法:
data = socket.recv(bufsize)
- 參數說明
- bufsize:指定一次最多接收的字節數。
示例
# 接收服務器的響應
data = client_socket.recv(1024)
print(f'收到服務器的響應: {data.decode()}')
2.5 socket.close()
- 功能:關閉套接字,釋放相關資源。
- 語法:
socket.close()
示例
# 關閉連接
client_socket.close()
完整示例代碼
下面是一個完整的 TCP 客戶端示例代碼,展示了上述方法的綜合運用:
import socket# 創建一個TCP/IPv4套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 服務器地址和端口
server_address = ('localhost', 8888)# 連接服務器
client_socket.connect(server_address)try:# 發送數據給服務器message = '你好,服務器!'client_socket.sendall(message.encode())# 接收服務器的響應data = client_socket.recv(1024)print(f'收到服務器的響應: {data.decode()}')
finally:# 關閉連接client_socket.close()
2.6 UDP 客戶端方法的差異
若使用 UDP 協議,客戶端不需要 connect 方法來建立連接,而是直接使用 sendto 和 recvfrom 方法進行數據的收發。下面是一個簡單的 UDP 客戶端示例:
import socket# 創建一個UDP/IPv4套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)# 服務器地址和端口
server_address = ('localhost', 9999)# 發送數據給服務器
message = '你好,服務器!'
client_socket.sendto(message.encode(), server_address)# 接收服務器的響應
data, server = client_socket.recvfrom(1024)
print(f'收到服務器的響應: {data.decode()}')# 關閉套接字
client_socket.close()