python中socket(套接字)庫詳細(xì)舉例解析
1. 前言
在 Python 開發(fā)中,socket 庫是一個非常重要的工具,它允許我們進(jìn)行網(wǎng)絡(luò)編程。通過 socket,程序可以在不同的機(jī)器之間進(jìn)行通信,這為我們構(gòu)建分布式系統(tǒng)、網(wǎng)絡(luò)服務(wù)等提供了基礎(chǔ)。無論是開發(fā)一個簡單的聊天程序,還是構(gòu)建復(fù)雜的網(wǎng)絡(luò)服務(wù)架構(gòu),socket 都是不可或缺的。本文將結(jié)合詳細(xì)的 Python 代碼,全面介紹 socket 庫的使用方法,讓你輕松掌握網(wǎng)絡(luò)編程的核心技能。
2. socket 庫基礎(chǔ)
2.1 什么是 socket?
socket(套接字)是通信的端點(diǎn),它是一個通信會話的抽象。在計算機(jī)網(wǎng)絡(luò)中,兩臺計算機(jī)之間要進(jìn)行通信,就需要在雙方建立 socket 連接,通過這個雙向通道進(jìn)行數(shù)據(jù)的發(fā)送和接收。
2.2 socket 的類型
主要有兩種常見的 socket 類型:
SOCK_STREAM :提供面向連接的、可靠的字節(jié)流服務(wù),基于 TCP 協(xié)議。它確保數(shù)據(jù)按照順序到達(dá),并且在數(shù)據(jù)傳輸過程中不會出現(xiàn)重復(fù)。
SOCK_DGRAM :提供無連接的、不可靠的 datagram 服務(wù),基于 UDP 協(xié)議。這種類型的數(shù)據(jù)傳輸不保證可靠性,數(shù)據(jù)可能會丟失或亂序到達(dá),但它的傳輸速度相對較快,適用于對實(shí)時性要求較高但對數(shù)據(jù)丟失不太敏感的場景,如視頻流傳輸。
3. 基于 TCP 的 socket 編程
3.1 TCP 服務(wù)器端代碼示例
import socket # 創(chuàng)建 socket 對象,AF_INET 表示使用 IPv4 地址,SOCK_STREAM 表示使用 TCP 協(xié)議 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 綁定 IP 地址和端口,這里綁定本地主機(jī)的 8080 端口 server_socket.bind(("localhost", 8080)) # 開始監(jiān)聽,監(jiān)聽隊(duì)列長度為 5 server_socket.listen(5) print("服務(wù)器開始監(jiān)聽...") # 接受客戶端連接,accept() 方法會阻塞等待客戶端連接 client_socket, client_address = server_socket.accept() print(f"客戶端 {client_address} 已連接") # 接收客戶端發(fā)送的數(shù)據(jù),1024 表示緩沖區(qū)大小 data = client_socket.recv(1024).decode() print(f"接收到客戶端消息:{data}") # 向客戶端發(fā)送數(shù)據(jù) response = "服務(wù)器已收到消息" client_socket.send(response.encode()) # 關(guān)閉連接 client_socket.close() server_socket.close()
3.2 TCP 客戶端代碼示例
import socket # 創(chuàng)建 socket 對象 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 連接到服務(wù)器,這里連接本地主機(jī)的 8080 端口 client_socket.connect(("localhost", 8080)) # 向服務(wù)器發(fā)送數(shù)據(jù) message = "Hello, Server!" client_socket.send(message.encode()) # 接收服務(wù)器返回的數(shù)據(jù) response = client_socket.recv(1024).decode() print(f"收到服務(wù)器回復(fù):{response}") # 關(guān)閉連接 client_socket.close()
3.3 代碼分析
在服務(wù)器端,
bind()
方法用于綁定 IP 地址和端口,使得服務(wù)器能夠監(jiān)聽指定地址和端口上的連接請求。listen()
方法則讓服務(wù)器進(jìn)入監(jiān)聽狀態(tài),等待客戶端的連接。accept()
方法是一個阻塞方法,它會等待客戶端的連接。當(dāng)客戶端連接成功后,會返回一個新的 socket 對象(用于和客戶端進(jìn)行通信)和客戶端的地址信息。客戶端通過
connect()
方法連接到服務(wù)器的指定 IP 地址和端口。數(shù)據(jù)的發(fā)送和接收分別通過
send()
和recv()
方法實(shí)現(xiàn),需要注意數(shù)據(jù)是以字節(jié)流的形式傳輸,所以在發(fā)送之前要使用encode()
方法將字符串編碼為字節(jié),接收后使用decode()
方法解碼為字符串。
4. 基于 UDP 的 socket 編程
4.1 UDP 服務(wù)器端代碼示例
import socket # 創(chuàng)建 socket 對象,SOCK_DGRAM 表示使用 UDP 協(xié)議 server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 綁定 IP 地址和端口 server_socket.bind(("localhost", 9090)) print("UDP 服務(wù)器啟動,等待客戶端消息...") while True: # 接收客戶端發(fā)送的數(shù)據(jù)和客戶端地址 data, client_address = server_socket.recvfrom(1024) print(f"收到客戶端 {client_address} 的消息:{data.decode()}") # 向客戶端發(fā)送數(shù)據(jù) response = "服務(wù)器已收到你的 UDP 消息" server_socket.sendto(response.encode(), client_address) # 如果收到特定消息就退出循環(huán) if data.decode() == "exit": break # 關(guān)閉 socket server_socket.close()
4.2 UDP 客戶端代碼示例
import socket # 創(chuàng)建 socket 對象 client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 向服務(wù)器發(fā)送數(shù)據(jù) server_address = ("localhost", 9090) message = "Hello, UDP Server!" client_socket.sendto(message.encode(), server_address) # 接收服務(wù)器返回的數(shù)據(jù) response, server_address = client_socket.recvfrom(1024) print(f"收到服務(wù)器 {server_address} 的回復(fù):{response.decode()}") # 再次發(fā)送消息并接收回復(fù)(測試多輪通信) message = "This is another message" client_socket.sendto(message.encode(), server_address) response, server_address = client_socket.recvfrom(1024) print(f"收到服務(wù)器回復(fù):{response.decode()}") # 發(fā)送退出消息 client_socket.sendto("exit".encode(), server_address) # 關(guān)閉連接 client_socket.close()
4.3 代碼分析
UDP 是無連接的,所以在服務(wù)器端不需要像 TCP 一樣調(diào)用
listen()
和accept()
方法來建立連接,而是直接通過recvfrom()
方法接收數(shù)據(jù)和客戶端地址。客戶端通過
sendto()
方法發(fā)送數(shù)據(jù),同時指定目標(biāo)服務(wù)器的地址和端口。recvfrom()
方法用于接收數(shù)據(jù)和服務(wù)器的地址。UDP 的這種通信方式使得數(shù)據(jù)的發(fā)送和接收相對簡單,但需要注意數(shù)據(jù)的丟失和亂序問題。
5. 總結(jié)
Python 中的 socket 庫是強(qiáng)大而靈活的網(wǎng)絡(luò)編程工具。通過本文的介紹和代碼示例,我們詳細(xì)了解了基于 TCP 和 UDP 協(xié)議的 socket 編程方法。TCP 提供了可靠的面向連接的通信,適用于對數(shù)據(jù)準(zhǔn)確性要求高的場景;UDP 則提供了簡單的無連接通信,適合對實(shí)時性要求較高但對數(shù)據(jù)丟失不太敏感的場景。在實(shí)際開發(fā)中,我們可以根據(jù)具體需求選擇合適的協(xié)議類型來構(gòu)建網(wǎng)絡(luò)應(yīng)用,從簡單的客戶端 - 服務(wù)器架構(gòu)到復(fù)雜的分布式系統(tǒng),socket 庫都能為我們提供堅(jiān)實(shí)的基礎(chǔ)。掌握 socket 編程,將為你打開網(wǎng)絡(luò)編程世界的大門,讓你能夠開發(fā)出各種具有網(wǎng)絡(luò)通信功能的應(yīng)用程序。
到此這篇關(guān)于python中socket(套接字)庫的文章就介紹到這了,更多相關(guān)python中socket套接字內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python中requests庫+xpath+lxml簡單使用
這篇文章主要介紹了python中requests庫+xpath+lxml簡單使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04詳解Python中圖像邊緣檢測算法的實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了python中圖像邊緣檢測算法的原理及實(shí)現(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05python數(shù)據(jù)類型bytes?和?bytearray的使用與區(qū)別
本文主要介紹了python數(shù)據(jù)類型bytes?和?bytearray的使用與區(qū)別,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02Python爬取奶茶店數(shù)據(jù)分析哪家最好喝以及性價比
這篇文章主要介紹了用Python告訴你奶茶哪家最好喝性價比最高,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-09-09python可以美化表格數(shù)據(jù)輸出結(jié)果的兩個工具
這篇文章主要介紹了python可以美化表格數(shù)據(jù)輸出結(jié)果的兩個工具,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-06-06python使用pyshp讀寫shp文件的實(shí)現(xiàn)
本文主要介紹了python使用pyshp讀寫shp文件的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03一文帶你精通Python中*args和**kwargs的應(yīng)用技巧
如果能在Python中創(chuàng)建適應(yīng)不同場景的函數(shù),而無需每次都重寫它們,會使得操作簡潔方便,這就是*args和**kwargs的魔力所在,下面我們就來看看它們的具體一些應(yīng)用技巧吧2024-03-03