淺析Python中的套接字編程
一、為什么使用套接字
套接字是網(wǎng)絡的基礎。它們使在兩個不同程序或設備之間的信息傳輸成為可能。例如,當您打開瀏覽器時,您作為客戶端正在與服務器建立連接以進行信息傳輸。
在深入探討這種通信之前,讓我們首先弄清楚這些插座的確切含義。
二、什么是套接字
一般而言,套接字是為發(fā)送和接收數(shù)據(jù)而構建的內(nèi)部端點。單個網(wǎng)絡將具有兩個套接字,每個通信設備或程序一個。這些套接字是IP地址和端口的組合。根據(jù)所使用的端口號,單個設備可以具有n個插槽。不同的端口可用于不同類型的協(xié)議。請看以下圖像,以了解有關一些常見端口號和相關協(xié)議的更多信息:
現(xiàn)在您已經(jīng)了解了套接字的概念,現(xiàn)在讓我們看一下Python的Socket模塊
三、如何在Python中實現(xiàn)Socket編程
要使用Python實現(xiàn)Socket編程,您將需要導入socket模塊或框架。該模塊由創(chuàng)建套接字并幫助它們彼此關聯(lián)所需的內(nèi)置方法組成。
一些重要的方法如下:
既然您已經(jīng)了解了套接字模塊的重要性,那么讓我們繼續(xù)看一下它如何為Python中的套接字編程創(chuàng)建服務器和客戶端。
四、什么是服務器
服務器可以是程序,計算機或專用于管理網(wǎng)絡資源的設備。服務器可以在同一臺設備或計算機上,也可以在本地連接到其他設備和計算機,甚至可以遠程連接。有各種類型的服務器,例如數(shù)據(jù)庫服務器,網(wǎng)絡服務器,打印服務器等。
服務器通常使用諸如socket.socket(),socket.bind(),socket.listen()等方法來建立連接并綁定到客戶端?,F(xiàn)在,讓我們編寫一個程序來創(chuàng)建服務器??紤]以下示例:
例子:
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
如您所見,創(chuàng)建套接字的第一個必要條件是導入套接字模塊。之后,使用socket.socket()方法創(chuàng)建服務器端套接字。
NOTE:
AF_INET是指Internet上的地址,它需要一對(主機,端口),其中主機可以是某個特定網(wǎng)站的URL或它的地址,并且端口號是整數(shù)。SOCK_STREAM用于創(chuàng)建TCP協(xié)議。
bind()方法接受兩個參數(shù)作為元組(主機,端口)。但是,最好使用4位數(shù)字的端口號,因為通常占用較小的端口號。listen()方法允許服務器接受連接。在這里,5是同時出現(xiàn)的多個連接的隊列。此處可以指定的最小值為0(如果您提供較小的值,則將其更改為0)。如果未指定任何參數(shù),則采用默認的合適參數(shù)。
在while循環(huán)允許接受連接永遠?!?clt”和“ adr”是客戶端對象和地址。print語句僅打印出客戶端套接字的地址和端口號。最后,clt.send用于發(fā)送字節(jié)數(shù)據(jù)。
現(xiàn)在我們的服務器已經(jīng)準備好了,讓我們繼續(xù)前進到客戶端。
五、什么是客戶端
客戶端是從服務器接收信息或服務的計算機或軟件。在客戶端服務器模塊中,客戶端從服務器請求服務。最好的例子是Web瀏覽器,例如Google Chrome,F(xiàn)irefox等。這些Web瀏覽器向Web服務器請求用戶指示的所需網(wǎng)頁和服務。其他示例包括在線游戲,在線聊天等。
現(xiàn)在讓我們看一下如何用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"))
第一步是導入套接字模塊,然后創(chuàng)建套接字,就像創(chuàng)建服務器時一樣。然后,要在客戶端-服務器之間創(chuàng)建連接,您需要通過指定(主機,端口)使用connect()方法。
注意:當客戶端和服務器位于同一臺計算機上時,將使用gethostname。(LAN –本地IP / WAN –公用IP)
在這里,客戶端希望從服務器接收一些信息,為此,您需要使用recv()方法,并且該信息存儲在另一個變量msg中。請記住,傳遞的信息將以字節(jié)為單位,并且在上述程序的客戶端中,一次傳輸最多可接收1024個字節(jié)(緩沖區(qū)大?。?。可以指定任意數(shù)量,具體取決于傳輸?shù)男畔⒘俊?/p>
最后,正在傳輸?shù)南M行解碼和打印。
既然您已經(jīng)知道如何創(chuàng)建客戶端-服務器程序,那么讓我們繼續(xù)看看如何執(zhí)行它們。
5.1、Echo Client-Server
要執(zhí)行這些程序,請打開命令提示符,進入創(chuàng)建了客戶端和服務器程序的文件夾,然后鍵入:
py server.py(在這里,server.py是服務器的文件名,您也可以使用py -3.7 server.py)
完成此操作后,服務器將開始運行。要執(zhí)行客戶端,請打開另一個cmd窗口,然后鍵入:
py client.py(此處,client.py是客戶端的文件名)
輸出(服務器):
(客戶)
讓我們通過將緩沖區(qū)大小減小到7來嘗試相同的程序,然后看看我們得到什么輸出:
輸出:
如您所見,連接在傳輸7個字節(jié)后終止。但這是一個問題,因為您尚未收到完整的信息,并且連接已關閉。讓我們繼續(xù)解決這個問題。
5.2、Multiple Communications
為了使連接一直持續(xù)到客戶端收到完整的信息,可以使用while循環(huán):
例子:
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個字節(jié)的形式接收完整的消息。
但是這一次,如您所見,連接不會終止,您也不知道何時會發(fā)生連接。除此之外,如果您實際上不知道客戶端將從服務器接收到的消息或信息有多大,該怎么辦。在這種情況下,您實際上可以在客戶端使用以下代碼:
例子:
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()
輸出如下圖所示:
輸出:
上面的代碼塊所做的全部工作是,檢查信息的大小,并一次將其打印在兩個字節(jié)的緩沖區(qū)中,再在完成連接后將其關閉。
六、傳輸Python對象
直到這里,您才有了傳輸字符串的訣竅。但是,Python中的套接字編程也允許您傳輸Python對象。這些對象可以是集合,元組,字典等任何對象。要實現(xiàn)此目的,您將需要導入Python的pickle模塊。
6.1、Python pickle模塊
當您實際上在python中序列化或反序列化對象時,Python pickle模塊就會出現(xiàn)。讓我們看一個小例子,
例子:
import pickle mylist=[1,2,'abc'] mymsg = pickle.dumps(mylist) print(mymsg)
輸出:
b'x80x03] qx00(Kx01Kx02Xx03x00x00x00abcqx01e。
如您所見,在上面的程序中,使用pickle模塊的dumps()函數(shù)對'mylist'進行了序列化。還要注意,輸出以“ b”開頭,這意味著它已轉換為字節(jié)。在套接字編程中,可以實現(xiàn)此模塊以在客戶端和服務器之間傳輸python對象。
6.2、如何使用pickle模塊傳遞python對象結構
當您將泡菜與套接字一起使用時,您絕對可以通過網(wǎng)絡傳輸任何內(nèi)容。讓我們寫下服務器端和客戶端對應項,以將列表從服務器傳輸?shù)娇蛻舳耍?/p>
服務器端:
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對象,需要從服務器發(fā)送到客戶端。這是通過首先使用dumps()序列化對象,然后將其轉換為字節(jié)來完成的?,F(xiàn)在讓我們寫下客戶端對應的內(nèi)容:
客戶端:
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循環(huán)將幫助我們跟蹤完整消息(complete_info)以及正在使用緩沖區(qū)接收的消息(rec_msg)。通過設置rec_設置消息,然后,在接收消息時,我所做的就是打印每個消息,并在大小為10的緩沖區(qū)中接收該消息。此大小可以是任何值,具體取決于您的個人選擇。
然后,如果收到的消息等于完整的消息,那么我只是將消息打印為已接收的完整信息,然后使用loads()將消息反序列化。上面程序的輸出如下:
這使我們結束了有關使用Socket進行編程的本文的結尾。希望您能清楚地理解所有概念。
以上就是淺析Python中的套接字編程的詳細內(nèi)容,更多關于Python套接字編程的資料請關注腳本之家其它相關文章!
- Python 網(wǎng)絡編程之UDP發(fā)送接收數(shù)據(jù)功能示例【基于socket套接字】
- Python socket 套接字實現(xiàn)通信詳解
- python使用原始套接字發(fā)送二層包(鏈路層幀)的方法
- python 基于TCP協(xié)議的套接字編程詳解
- Python socket套接字實現(xiàn)C/S模式遠程命令執(zhí)行功能案例
- Python網(wǎng)絡編程之TCP套接字簡單用法示例
- Python網(wǎng)絡編程之TCP與UDP協(xié)議套接字用法示例
- python利用socketserver實現(xiàn)并發(fā)套接字功能
- Python網(wǎng)絡編程 Python套接字編程
- 詳解python3中socket套接字的編碼問題解決
相關文章
Python編寫一個驗證碼圖片數(shù)據(jù)標注GUI程序附源碼
這篇文章主要介紹了Python編寫一個驗證碼圖片數(shù)據(jù)標注GUI程序,本文給大家附上小編精心整理的源碼,需要的朋友可以參考下2019-12-12python+tkinter+mysql做簡單數(shù)據(jù)庫查詢界面
本文主要介紹了python+tkinter+mysql做簡單數(shù)據(jù)庫查詢界面,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01python實現(xiàn)將讀入的多維list轉為一維list的方法
今天小編就為大家分享一篇python實現(xiàn)將讀入的多維list轉為一維list的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-06-06pandas如何將datetime64[ns]轉為字符串日期
這篇文章主要介紹了pandas如何將datetime64[ns]轉為字符串日期,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07一篇文章帶你搞定Ubuntu中打開Pycharm總是卡頓崩潰
這篇文章主要介紹了一篇文章帶你搞定Ubuntu中打開Pycharm總是卡頓崩潰,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-11-11python實現(xiàn)讀取類別頻數(shù)數(shù)據(jù)畫水平條形圖案例
這篇文章主要介紹了python實現(xiàn)讀取類別頻數(shù)數(shù)據(jù)畫水平條形圖案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04Python?Excel操作從零學習掌握openpyxl用法
這篇文章主要為大家介紹了Python?Excel操作從零學習掌握openpyxl用法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08