在現今的互聯網當中,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中文網其他相關文章!

网络ms是指网络延迟了以ms(毫秒)为单位的数据。网络中的ms就是指的毫秒,ms数值则代表了网络的延时情况,如果ms数值越高,说明当前网络延迟状况严重,用户进行游戏时会出现卡顿现象;如果ms数值越低,也就代表了网络状况流畅。

网络接入已满的意思是指当前连接的WIFI已经达到预定的设备数量了,无法再接入新的设备了;通俗说就是路由器设置了只能连接N个设备,现在已经足够了,所以新的设备就连接不了。

每一台主机都有唯一的地址标识称为“IP地址”。IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个唯一的逻辑地址,以此来屏蔽物理地址的差异。由于有这种唯一的地址,才保证了用户在连网的计算机上操作时,能够高效而且方便地从千千万万台计算机中选出自己所需的对象来。

网络忙的意思就是“网络忙线”,指对方拒绝接听电话或者当信号不好时,就会出现提示网络忙;提示网络忙的其他原因有:1、所处的电话基站的无线信道太少或打电话的人太多;2、晚上IP路由比较忙,所以会经常听到网络忙的提示。

chn-ct是中国电信的4G网络。CHN-CT全称China Telecom(FDD-LTE),翻译过来是中国电信(第四代移动通信网络),属于中国电信的移动通信网络,只有电信用户可以使用。CHN-CT技术包括TD-LTE和FDD-LTE两种制式,但LTE只是3.9G,因此在严格意义上其还未达到4G的标准;只有升级版的LTE Advanced才满足国际电信联盟对4G的要求。

进网许可和进网试用的区别:1、标志上的颜色不同,进网试用的标志颜色是绿色,而进网许可标志是蓝色的;2、两者的使用时间不同,进网试用是给用户一年的试用期,但是进网许可是直接进行使用,没有时间限制。

evdo是电信的CDMA网络的3G网络制式,最高速度可以达到3.1M左右;evdo是三个单词的缩写,全称为“CDMA2000 1xEV-DO”,已被国际电联ITU接纳为国际3G标准。

0×01前言ChatGPT(Chat Generative Pre-trained Transformer)是当今备受瞩目的智能AI聊天机器人之一。它不仅能够实现基本的语言交流,还具备许多强大的功能,例如文章撰写、代码脚本编写、翻译等等。那么我们是否可以利用 ChatGpt 去辅助我们完成一些工作呢?比如当一个产品存在安全风险需要漏洞检测时,我们就需要编写对应的POC来实现。目前进行多次验证,我们初步证实了这个实验的可行性,可以训练 ChatGPT 去编写简单的 PoC,但是它对细节的把控并不够


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

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

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能