Python Socket程式設計詳解及實作指南
在現今的互聯網當中,Socket 協定是最重要的基礎之一。本文涵蓋了在 Python 中處理 Socket 程式設計的所有領域。
為什麼使用Sockets
Sockets 是組成當今網路的各種通訊協議,這些協議使得在兩個不同的程式或設備之間傳輸訊息成為可能。例如,當我們開啟瀏覽器時,我們作為客戶機就會建立與伺服器的連線以傳輸訊息。
在深入研究這個溝通原理之前,讓我們先弄清楚 Sockets 到底是什麼。
什麼是 Sockets
一般來說,Socket 是為發送和接收資料而建構的內部應用協定。單一網路將有兩個 Sockets,每個 Sockets 用於通訊設備或程序,這些 Sockets 是IP位址和連接埠的組合。根據使用的連接埠號,單一裝置可以有「n」個 Sockets,不同的連接埠可用於不同類型的協定。
下圖展示了一些常見連接埠號碼和相關協定的資訊:
協定 |
連接埠號碼 |
#Python 函式庫 | 應用程式 |
HTTP |
##80 |
httplib,urllib,requests |
#網頁,網站 |
|
|||
# | 119 |
nttplib |
訊息傳輸 |
SMTP |
#25 |
smtplib |
發送郵件 |
#Telnet |
23 |
telnetlib |
#命令列 |
##POP3 |
#110 |
#poplib |
接收郵件 |
Gopher | ##70 | gopherlib文件傳輸 |
現在我們已經了解了Sockets 的概念,現在讓我們來看看Python 的Socket 模組
如何在Python 中實作Socket 程式設計
##要在Python 中實作Socket 編程,需要導入socket 模組。 該模組的一些重要方法如下:方法 |
| #描述
#socket.socket() |
用於建立socket(伺服器端和客戶端都需要建立) |
#socket.accept() |
用於接受連線。它會傳回一對值(conn,address),其中conn是用於發送或接收資料的新socket 對象,address是連接另一端的socket 地址 |
socket.bind() |
用於綁定到指定為參數的位址 |
socket.close() |
用於關閉socket |
現在我們已經了解了 socket 模組的重要性,接下來讓我們來看看如何在 Python 中建立伺服器和客戶機。
什麼是伺服器
伺服器或是一個程式、一台計算機,或是專門用來管理網路資源的設備。伺服器可以位於同一設備或計算機上,也可以本地連接到其他設備和計算機,甚至可以遠端連接。有各種類型的伺服器,如資料庫伺服器、網頁伺服器、列印伺服器等。
伺服器通常使用socket.socket(),socket.bind(),socket.listen()等來建立連線並綁定到客戶端,現在讓我們寫一個程式來建立伺服器。
import socket s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((socket.gethostname(),1234)) #port number can be anything between 0-65535(we usually specify non-previleged ports which are > 1023) s.listen(5) while True: clt,adr=s.accept() print(f"Connection to {adr}established") #f string is literal string prefixed with f which #contains python expressions inside braces clt.send(bytes("Socket Programming in Python","utf-8 ")) #to send info to clientsocket
建立 socket 的第一個必要條件是導入相關模組。之後是使用socket.socket()方法建立伺服器端 socket。
AF_INET 是指來自Internet 的位址,它需要一對(主機、連接埠),其中主機可以是某個特定網站的URL 或其位址,連接埠號碼為整數。 SOCK_STREAM 用於建立 TCP 協定。
bind()方法接受兩個參數作為元組(主機、連接埠)。這裡要注意的是最好使用4位的連接埠號,因為較低的連接埠號碼通常被佔用或是系統預留的。 listen()方法允許伺服器接受連接,5是同時接受的多個連接的佇列。此處可以指定的最小值為0,如果未指定參數,則採用預設的適當參數。
while循環允許永遠接受連接,clt和adr是客戶端物件和位址,print語句只是列印出客戶端socket 的位址和連接埠號,最後,clt.send用於以位元組為單位發送資料。
現在我們的伺服器已經設定好了,讓我們繼續往客戶端前進。
什麼是客戶端
客戶端是從伺服器接收訊息或服務的電腦或軟體。在客戶端-伺服器模型中,客戶端從伺服器請求服務。最好的例子是 Google Chrome、Firefox 等 Web 瀏覽器,這些 Web 瀏覽器根據使用者的指示請求 Web 伺服器提供所需的網頁和服務。其他範例包括線上遊戲、線上聊天等。
現在,讓我們看看如何用 Python 程式語言編寫客戶端程式:
import socket s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((socket.gethostname(), 2346)) msg=s.recv(1024) print(msg.decode("utf-8"))
首先仍然是導入 socket 模組,然後像創建伺服器時那樣創建套接字。接著要在客戶端伺服器之間建立連接,需要透過指定(host,port)使用 connect()方法。
注意:當客戶端和伺服器位於同一台電腦上時,需要使用gethostname。 (LAN–localip/WAN–publicip)
在這裡,客戶端希望從伺服器接收一些訊息,為此,我們需要使用recv()方法,訊息儲存在另一個變數msg中。需要注意的是正在傳遞的訊息將以位元組為單位,在上述程式的客戶端中,一次傳輸最多可以接收1024位元組(緩衝區大小)。根據傳輸的資訊量,可以將其指定為任意數量。
最後,再解碼並列印正在傳輸的訊息。
現在我們已經了解如何建立客戶端-伺服器程序,接下來讓我們看看它們需要如何執行。
客戶端伺服器互動
要執行這些程序,需要開啟命令程序,進入建立客戶端和伺服器程式的資料夾,然後鍵入:
py server.py #这里,server.py 是服务器的文件名
不出意外伺服器開始執行
要執行客戶端,需要開啟另一個cmd窗口,然後鍵入:
pyclient.py
下面讓我們將緩衝區大小減少到7,來看看相同的程式會怎麼樣
#如圖所示,傳送7個位元組後,連線終止。
其實這是一個問題,因為我們尚未收到完整的訊息,但是連接卻提前關閉了,下面讓我們來解決這個問題。
多重通訊
為了在客戶端收到完整訊息之前繼續連接,我們可以使用while循環
import socket s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((socket.gethostname(), 2346)) while True: msg=s.recv(7) print(msg.decode("utf-8"))
如此修改之後,每次傳輸將以7個字節接收完整訊息。
但這又引來了另一個問題,連結永遠不會終止,你永遠不知道什麼時候會終止。此外,如果我們實際上不知道客戶端將從伺服器接收到的訊息或資訊有多大,該怎麼辦。在這種情況下,我們需要繼續完善程式碼
complete_info='' while True: msg = s.recv(7) if len(msg)<=0: break complete_info += msg.decode("utf-8") print(complete_info)
在伺服器端,使用close()方法,如下所示:
clt.close()
輸出如下:
程序会检查信息的大小,并将其打印到一次两个字节的缓冲区中,然后在完成连接后关闭连接。
传输 Python 对象
目前为止我们仅仅掌握了传递字符串的方法,但是,Python 中的 Socket 编程也允许我们传输 Python 对象。这些对象可以是集合、元组、字典等。要实现这一点,需要用到 Python 的 pickle 模块。
Python pickle模块
当我们实际序列化或反序列化 Python 中的对象时,就会使用到 Python pickle 模块。让我们看一个小例子
import pickle mylist=[1,2,'abc'] mymsg = pickle.dumps(mylist) print(mymsg)
Output:
b’x80x03]qx00(Kx01Kx02Xx03x00x00x00abcqx01e.’
在上面的程序中,mylist是使用pickle模块的dumps()函数序列化的。还要注意,输出以b开头,表示它已转换为字节。在 socket 编程中,可以实现此模块以在客户端和服务器之间传输 python 对象。
如何使用 pickle 模块传输 Python 对象
当我们将 pickle 与 socket 一起使用时,完全可以通过网络传输任何内容。
先来看看服务端代码
Server-Side:
import socket import pickle a=10 s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((socket.gethostname(), 2133))#binding tuple s.listen(5) while True: clt , adr = s.accept() print(f"Connection to {adr}established") m={1:"Client", 2:"Server"} mymsg = pickle.dumps(m)#the msg we want to print later mymsg = {len(mymsg):{a}}"utf-8") + mymsg clt.send(mymsg)
这里,m是一个字典,它基本上是一个需要从服务器发送到客户端的 Python 对象。这是通过首先使用dumps()序列化对象,然后将其转换为字节来完成的。
现在,让我们记下客户端:
Client-Side:
import socket import pickle a=10 s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((socket.gethostname(), 2133)) while True: complete_info = b'' rec_msg = True while True: mymsg = s.recv(10) if rec_msg: print(f"The length of message = {mymsg[:a]}") x = int (mymsg[:a ] ) rec_msg = False complete_info += mymsg if len(complete_info)-a == x: print("Recieved the complete info") print(complete_info[a:]) m = pickle.loads(complete_info[a:]) print(m) rec_msg = True complete_info = b'' print(complete_info)
第一个while循环将帮助我们跟踪完整的消息(complete_info)以及正在使用缓冲区接收的消息(rec_msg)。
然后,在接收消息时,我们所做的就是打印每一位消息,并将其放在大小为10的缓冲区中接收。此大小可以是任何大小,具体取决于个人选择。
然后如果收到的消息等于完整消息,我们只会将消息打印为收到的完整信息,然后使用loads()反序列化消息。
输出如下:
以上是Python Socket程式設計詳解及實作指南的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

如果您在Windows11上突然出現緩慢的互聯網連接,並且您已經嘗試了書中的所有技巧,那麼它可能與您的網絡無關,而是與您的最大傳輸單元(MTU)無關。如果您的系統發送或接收具有錯誤MTU大小的數據,則可能會出現問題。在這篇文章中,我們將了解如何在Windows11上更改MTU大小以實現流暢和不間斷的網路連線。 Windows11中的預設MTU大小是多少? Windows11中的預設MTU大小為1500,這是允許的最大值。 MTU代表最大傳輸單位。這是可以在網路上發送或接收的最大資料包大小。每個支援網
![WLAN擴充模組已停止[修復]](https://img.php.cn/upload/article/000/465/014/170832352052603.gif?x-oss-process=image/resize,m_fill,h_207,w_330)
如果您的Windows電腦上的WLAN擴充模組出現問題,可能會導致您與網際網路中斷連線。這種情況常常讓人感到困擾,但幸運的是,本文提供了一些簡單的建議,可以幫助您解決這個問題,讓您的無線連線重新正常運作。修復WLAN擴充模組已停止如果您的Windows電腦上的WLAN可擴充性模組已停止運作,請依照下列建議進行修復:執行網路和Internet故障排除程式停用並重新啟用無線網路連線重新啟動WLAN自動設定服務修改電源選項修改高級電源設定重新安裝網路適配器驅動程式運行一些網路命令現在,讓我們來詳細看

我們在連接網路時需要使用正確的dns才可以上網。同理,如果我們使用了錯誤的dns設定就會提示dns伺服器錯誤了,這時候我們可以嘗試在網路設定中選擇自動取得dns來解決,以下就一起來看下具體解決方法吧。 win11網路dns伺服器錯誤怎麼辦方法一:重新設定DNS1、首先,點選工作列中的開始進入,在其中找到並點選「設定」圖示按鈕。 2、然後點選左側欄中的「網路&Internet」選項指令。 3、然後在右側找到「乙太網路」選項,點選進入。 4、之後,點選DNS伺服器指派中的“編輯”,最後將DNS設定為“自動(D

什麼是「網路錯誤下載失敗」問題?在我們深入研究解決方案之前,讓我們先了解「網路錯誤下載失敗」問題的含義。當下載過程中網路連線中斷時,通常會發生此錯誤。它可能由於各種原因而發生,例如互聯網連接薄弱、網路擁塞或伺服器問題。發生此錯誤時,下載將停止,並顯示錯誤訊息。如何修復失敗的網路錯誤下載?在存取或下載必要的文件時,遇到「網路錯誤下載失敗」可能會成為障礙。無論您是使用Chrome等瀏覽器還是Google雲端硬碟和Google相簿等平台,都會彈出此錯誤,從而造成不便。以下是幫助您導覽和解決此問題的分

如果WDMyCloud未在Windows11的網路上顯示,這可能是一個大問題,尤其是當您將備份或其他重要檔案儲存在其中時。對於經常需要存取網路儲存的用戶來說,這可能是一個大問題,因此在今天的指南中,我們將向您展示如何永久解決此問題。為什麼WDMyCloud未顯示在Windows11網路上?您的MyCloud裝置、網路介面卡或網路連線未正確配置。電腦上未安裝SMB功能。 Winsock的臨時故障有時會導致此問題。如果我的雲端未顯示在網路上,我該怎麼辦?在我們開始修復問題之前,您可以執行一些初步檢查:

這篇文章將介紹Win10系統網路顯示地球標誌但無法上網的解決方法。文章將提供詳細的操作步驟,幫助讀者解決Win10網路顯示地球無法上網的問題。方法一:直接重啟先檢查網路線是否沒插好,寬頻是否欠費,路由器或光貓可能會卡死,這時需重新啟動路由器或光貓。假如目前電腦沒有重要的事宜在操作,能直接重啟電腦,大部分的小問題能透過重新啟動電腦來快速解決。如果確定寬頻沒有欠費,網路正常,那便是另一回事。方法二:1、按【Win】鍵,或點選左下角的【開始選單】,在開啟的選單項目中,點選電源按鈕上方的齒輪狀圖標,這個就是【設

LAN喚醒是Windows11上的網路功能,有了它,您可以遠端將電腦從休眠或睡眠模式喚醒。雖然臨時用戶不經常使用它,但此功能對於使用有線網路的網路管理員和高級用戶非常有用,今天我們將向您展示如何設定它。如何知道我的電腦是否支援LAN喚醒?要使用此功能,您的電腦需要以下各項:PC需要連接到ATX電源,以便您可以遠端將其從睡眠模式喚醒。需要建立存取控制清單並將其新增至網路中的所有路由器。網路卡需要支援喚醒區域網路功能。要使此功能正常運作,兩台電腦需要位於同一網路上。雖然大多數以太網適配器通過以

為了確保您的網路連線正常運作或解決問題,有時您需要檢查Windows11上的網路連線詳細資訊。透過這樣做,您可以查看各種信息,包括您的IP位址、MAC位址、連結速度、驅動程式版本等,在本指南中,我們將向您展示如何做到這一點。如何在Windows11上找到網路連線詳細資訊? 1.使用「設定」應用程式按+鍵開啟Windows設定。 WindowsI接下來,導覽至左窗格中的網路和互聯網,然後選擇您的網路類型。在我們的例子中,這就是乙太網路。如果您使用的是無線網絡,請改為選擇Wi-Fi網路。在螢幕底部,您應該會看
