Python 的 Socket 模組提供便捷的網路程式設計介面,讓開發者能輕鬆建立 TCP 和 UDP 應用程式。建立 TCP 伺服器需使用 socket.SOCK_STREAM 引數,繫結 IP 和埠,並監聽連線請求。客戶端則需建立相同型別的 Socket 並連線到伺服器。UDP 通訊使用 socket.SOCK_DGRAM,透過 sendto() 和 recvfrom() 進行資料交換,無需建立連線。此外,Python 也提供 http.client 和 urllib.request 等模組,簡化 HTTP 請求的處理,讓開發者能更有效率地操作網頁內容。
使用Socket進行TCP客戶端與伺服器實作
在本章節中,我們將介紹如何使用Python的Socket模組來建立一個簡單的TCP客戶端與伺服器,以實作客戶端與伺服器之間的訊息傳遞。
使用Socket建立TCP伺服器
首先,我們需要建立一個Socket物件作為伺服器。以下是一個簡單的TCP伺服器實作範例:
import socket
import threading
SERVER_IP = "127.0.0.1"
SERVER_PORT = 9998
# 建立Socket物件
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 繫結IP與Port
server.bind((SERVER_IP, SERVER_PORT))
# 監聽連線請求
server.listen(5)
print("[*] Server Listening on %s:%d" % (SERVER_IP, SERVER_PORT))
def handle_client(client_socket):
# 接收客戶端請求
request = client_socket.recv(1024)
print("[*] Received request : %s from client %s" % (request, client_socket.getpeername()))
# 回傳確認訊息
client_socket.send(bytes("ACK", "utf-8"))
while True:
# 接受客戶端連線請求
client, addr = server.accept()
client.send("I am the server accepting connections...".encode())
print("[*] Accepted connection from: %s:%d" % (addr[0], addr[1]))
handle_client(client)
client.close()
server.close()
內容解密:
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM):建立一個TCP Socket物件。server.bind((SERVER_IP, SERVER_PORT)):將Socket物件繫結到指定的IP與Port。server.listen(5):開始監聽連線請求,最大連線數為5。handle_client(client_socket):處理客戶端請求的函式,接收客戶端訊息並回傳確認訊息。
使用Socket建立TCP客戶端
接下來,我們需要建立一個Socket物件作為客戶端,以連線到上述的TCP伺服器。以下是一個簡單的TCP客戶端實作範例:
import socket
host = "127.0.0.1"
port = 9998
try:
# 建立Socket物件
mysocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 連線到伺服器
mysocket.connect((host, port))
print('Connected to host ' + str(host) + ' in port: ' + str(port))
# 接收伺服器訊息
message = mysocket.recv(1024)
print("Message received from the server", message)
except Exception as e:
print("Error:", e)
內容解密:
mysocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM):建立一個TCP Socket物件。mysocket.connect((host, port)):連線到指定的伺服器IP與Port。message = mysocket.recv(1024):接收伺服器傳來的訊息。
圖示說明
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333
title 圖示說明
rectangle "連線請求" as node1
rectangle "接收請求" as node2
rectangle "回傳訊息" as node3
node1 --> node2
node2 --> node3
@enduml此圖示說明瞭客戶端與伺服器之間的連線請求與訊息傳遞流程。
網路程式設計中的Socket應用:TCP與UDP協定實作
簡介
在網路程式設計中,Socket是用於實作不同主機之間通訊的重要工具。Python提供了強大的socket模組,使得開發者能夠輕鬆建立根據TCP或UDP協定的客戶端-伺服器架構應用程式。本篇文章將探討如何使用Python的socket模組來實作TCP和UDP協定下的訊息傳遞。
TCP協定下的Socket程式設計
TCP(傳輸控制協定)是一種導向連線的協定,能夠確保資料的可靠傳輸。在Python中,建立TCP Socket需要使用socket.SOCK_STREAM引數。
實作TCP伺服器
首先,我們來建立一個簡單的TCP伺服器。伺服器端程式碼如下:
import socket
SERVER_IP = "127.0.0.1"
SERVER_PORT = 6789
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((SERVER_IP, SERVER_PORT))
server_socket.listen(5)
print(f"[*] 伺服器監聽於 {SERVER_IP}:{SERVER_PORT}")
while True:
client_socket, address = server_socket.accept()
data = client_socket.recv(1024)
print(f"收到來自 {address} 的訊息:{data.decode()}")
response = "你好,客戶端!"
client_socket.send(response.encode())
client_socket.close()
實作TCP客戶端
接下來,建立一個TCP客戶端來與伺服器進行通訊。客戶端程式碼如下:
import socket
SERVER_IP = "127.0.0.1"
SERVER_PORT = 6789
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((SERVER_IP, SERVER_PORT))
while True:
message = input("輸入你的訊息 > ")
client_socket.send(message.encode())
if message == "quit":
break
response = client_socket.recv(1024)
print(f"來自伺服器的回應:{response.decode()}")
client_socket.close()
程式碼解析
伺服器端:
- 使用
socket.socket(socket.AF_INET, socket.SOCK_STREAM)建立TCP Socket。 bind()方法將Socket繫結到特定的IP和埠。listen()方法使伺服器進入監聽狀態,準備接受客戶端連線。accept()方法接受客戶端連線請求,並傳回客戶端Socket和地址。
- 使用
客戶端:
- 同樣使用
socket.socket(socket.AF_INET, socket.SOCK_STREAM)建立TCP Socket。 connect()方法用於連線伺服器。- 使用
send()和recv()方法進行資料傳輸。
- 同樣使用
UDP協定下的Socket程式設計
UDP(使用者資料報協定)是一種無連線的協定,不保證資料的可靠傳輸,但具有較高的傳輸效率。在Python中,建立UDP Socket需要使用socket.SOCK_DGRAM引數。
實作UDP伺服器
UDP伺服器端程式碼如下:
import socket
SERVER_IP = "127.0.0.1"
SERVER_PORT = 6789
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind((SERVER_IP, SERVER_PORT))
print(f"[*] UDP伺服器監聽於 {SERVER_IP}:{SERVER_PORT}")
while True:
data, address = server_socket.recvfrom(4096)
print(f"收到來自 {address} 的訊息:{data.decode().strip()}")
response = "你好,客戶端!"
server_socket.sendto(response.encode(), address)
實作UDP客戶端
UDP客戶端程式碼如下:
import socket
SERVER_IP = "127.0.0.1"
SERVER_PORT = 6789
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
address = (SERVER_IP, SERVER_PORT)
while True:
message = input("輸入你的訊息 > ")
if message == "quit":
break
client_socket.sendto(message.encode(), address)
response, addr = client_socket.recvfrom(4096)
print(f"來自伺服器的回應:{response.decode()}")
client_socket.close()
程式碼解析
伺服器端:
- 使用
socket.SOCK_DGRAM建立UDP Socket。 - 使用
recvfrom()接收客戶端訊息,並使用sendto()回應客戶端。
- 使用
客戶端:
- 同樣使用
socket.SOCK_DGRAM建立UDP Socket。 - 使用
sendto()傳送訊息給伺服器,並使用recvfrom()接收伺服器回應。
- 同樣使用
HTTP程式設計
本章將介紹HTTP協定,並探討如何使用Python檢索和操作網頁內容。我們還將檢視標準的urllib函式庫,以及requests和httpx套件。此外,我們將介紹第三方requests模組,它是urllib的一個非常流行的替代方案,具有優雅的介面和強大的功能集,是簡化HTTP工作流程的絕佳工具。最後,我們將介紹HTTP身份驗證機制,以及如何使用requests模組進行管理。
本章將為我們提供在Python中使用不同模組來向Web服務或REST API發出請求的基礎。
本章涵蓋的主題
- 介紹HTTP協定
- 使用
http.client建立HTTP客戶端 - 使用
urllib.request建立HTTP客戶端 - 使用
requests建立HTTP客戶端 - 使用
httpx建立HTTP客戶端 - 使用Python進行身份驗證機制
技術需求
在開始閱讀本章之前,您應該具備Python程式設計的基礎知識,並對HTTP協定有一定的瞭解。我們將使用Python 3.7版本,可在www.python.org/downloads取得。
介紹HTTP協定
HTTP是一種應用層協定,定義了客戶端、代理伺服器和伺服器之間進行資訊交換的規則。它基本上由兩個元素組成:
- 由客戶端發出的請求,向伺服器請求特定資源,該資源由URL指定。
- 由伺服器發出的回應,提供客戶端請求的資源。
HTTP協定是一種無狀態的超文字資料傳輸協定,不會儲存客戶端和伺服器之間交換的資訊。由於它是一種無狀態的協定,因此需要使用其他技術來儲存交換資料,例如Cookie(儲存在客戶端的值)或Session(在伺服器端保留的臨時記憶體空間,用於儲存一個或多個HTTP交易的資訊)。
伺服器會傳回一個HTTP程式碼,指示客戶端請求的操作結果。此外,請求可以使用標頭在請求和回應中包含額外的資訊。
同樣重要的是要注意,HTTP協定在底層使用Socket來建立客戶端-伺服器連線。在Python中,我們可以使用更高層級的模組,它抽象了底層的Socket服務。
檢視狀態碼
每次向Web伺服器發出請求時,它都會接收並處理該請求,然後傳回所請求的資源以及HTTP標頭。HTTP回應的狀態碼指示特定的HTTP請求是否已成功完成。
我們可以使用其status屬性讀取回應的狀態碼。值200是一個HTTP狀態碼,告訴我們請求已成功:
>>> response.status
200
狀態碼分為以下幾類別:
- 100:資訊
- 200:成功
- 300:重新導向
- 400:客戶端錯誤
- 500:伺服器錯誤
在300型別的程式碼中,我們可以找到302重新導向程式碼,它指示由location標頭給出的特定URL已被臨時移動,直接將它們導向新的位置。另一個我們可以找到的程式碼是307,它在瀏覽器檢測到URL正在使用HTTPS的情況下用作內部重新導向。
使用http.client建立HTTP客戶端
Python提供了一些模組來建立HTTP客戶端。主要的函式庫模組是http.client和urllib.request。這些模組具有不同的功能,但對於大多數的Web測試都很有用。我們還可以找到提供了對標準函式庫的一些改進的requests模組。要了解更多關於這些請求的資訊,請存取https://docs.python.org/3/library/http.client.html。
讓我們首先了解http.client模組。 http.client模組定義了一個實作HTTPConnection類別的類別。此類別接受網域和埠作為引數。網域是必需的,而埠是可選的。此類別的一個例項表示與HTTP伺服器的交易。
範例程式碼
import http.client
connection = http.client.HTTPConnection("www.google.com")
connection.request("GET", "/")
response = connection.getresponse()
print(type(response))
print(response.status, response.reason)
if response.status == 200:
data = response.read()
print(data)
內容解密:
http.client.HTTPConnection("www.google.com"):建立一個與www.google.com的HTTP連線。connection.request("GET", "/"):向伺服器發出GET請求,請求根目錄("/")。response = connection.getresponse():取得伺服器的回應。print(response.status, response.reason):列印回應的狀態碼和原因短語。if response.status == 200::檢查狀態碼是否為200(表示成功)。data = response.read():讀取回應的內容。print(data):列印回應的內容。
使用urllib.request建立HTTP客戶端
urllib.request套件是Python標準函式庫中推薦用於HTTP任務的套件。 urllib套件具有更簡單的介面,並且能夠管理與HTTP請求相關的所有任務。
範例程式碼
#! /usr/bin/env python3
import urllib.request
import urllib.parse
內容解密:
import urllib.request:匯入urllib.request模組,用於處理HTTP請求。import urllib.parse:匯入urllib.parse模組,用於解析URL。
透過本章,我們學習瞭如何使用Python中的不同模組來建立HTTP客戶端,包括http.client和urllib.request。這些知識將幫助我們更好地理解和處理HTTP請求,為進一步探索網路程式設計打下堅實的基礎。