Pythony運維入門之Socket網(wǎng)絡(luò)編程詳解
Socket是什么?
Socket 是電腦網(wǎng)絡(luò)中進(jìn)程間數(shù)據(jù)流的端點Socket 是操作系統(tǒng)的通信機(jī)制應(yīng)用程序通過Socket進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)的傳輸
首先,簡單了解一下TCP通信過程:
TCP三次握手(面試??迹?br /> 第一次握手:客戶端 發(fā)送SYN報文,設(shè)置隨機(jī)數(shù)序號X,服務(wù)器由SYN=1知道,客戶端要求建立聯(lián)機(jī)
第二次握手:服務(wù)器端接收到客戶端的報文之后,經(jīng)過處理,返回給客戶端SYN+ACK報文,同時設(shè)置隨機(jī)序號Y,此時返回的報文確認(rèn)ACK=X+1
第三次握手:接收到報文的客戶端,會在處理確認(rèn)之后,再發(fā)送一個報文給服務(wù)器端,此時確認(rèn)為ACK=Y+1
服務(wù)器端接收到客戶端發(fā)送的報文之后,會在服務(wù)器端與客戶端形成一種通路,此后的數(shù)據(jù)就可以在這個通路上就可以傳輸。
Socket使用TCP協(xié)議的通信過程與上述相當(dāng)類似:
Socket通信方式
Socket分為TCP和UDP兩種不同的通信方式
為什么選擇 Socket?
Socket是基礎(chǔ)應(yīng)用,適應(yīng)多種網(wǎng)絡(luò)協(xié)議,服務(wù)器的傳輸大量涉及網(wǎng)絡(luò)協(xié)議,離不開Socket的應(yīng)用
以下編寫簡單的服務(wù)器和客戶端程序(以本機(jī)為例):
服務(wù)器端程序:
導(dǎo)入socket模塊(需要預(yù)先pip) import socket #創(chuàng)建實例 sk = socket.socket() #鼠標(biāo)放在內(nèi)建函數(shù)上,Ctrl+B,可以查看源碼 ip_port = ("127.0.0.1",8888) #綁定ip和port,以本機(jī)(127.0.0.1)和其他端口(8888)為例 sk.bind(ip_port) #綁定監(jiān)聽 sk.listen(5) #最大連接數(shù),大多數(shù)程序設(shè)置5足夠 print("正在接受數(shù)據(jù)") #打印一行提示信息 conn,address =sk.accept() #接收數(shù)據(jù) msg ="hello world" #定義數(shù)據(jù) conn.send(msg.encode()) #返回信息 , python3發(fā)送和接收網(wǎng)絡(luò)數(shù)據(jù)是byte類型,如果發(fā)送的是str類型就需要進(jìn)行編碼 conn.close() #關(guān)閉連接
客戶端程序:
#導(dǎo)入socket模塊 import socket client = socket.socket() #實例初始化 ip_port = ("127.0.0.1", 8888) #訪問服務(wù)器端的ip和端口 client.connect(ip_port) #連接服務(wù)器 data = client.recv(1024) #接收服務(wù)器信息 print(data.decode()) #打印信息,python3是傳輸byte類型 ,需要編碼。
實現(xiàn)socket客戶端一次連接中連續(xù)消息發(fā)送:
server端:
#導(dǎo)入socket模塊 import socket import random sk=socket.socket() #創(chuàng)建實例 ip_port =("127.0.0.1",8888) #定義綁定IP和port sk.bind(ip_port) #綁定監(jiān)聽 sk.listen(5) #設(shè)置最大連接數(shù) while True: #連續(xù)接收數(shù)據(jù) print("正在等待接收數(shù)據(jù)。。。。。") #提示信息 server,address=sk.accept() #接收數(shù)據(jù) msg='歡迎來到socket世界' #定義信息 server.send(msg.encode()) #返回信息 while True: #連續(xù)接受客戶端發(fā)送的消息 data=server.recv(1024) #接收客戶端信息 print(data.decode()) #打印獲取的數(shù)據(jù),實際開發(fā)生產(chǎn)一般不打印 if data == b'exit': #接收到退出命令 break sever.send(data.encode()) #處理客戶端數(shù)據(jù) sever.send(str(random.randint(1,50000)).encode()) #發(fā)送隨機(jī)數(shù)據(jù)信息 conn.close() #主動關(guān)閉連接
client端:
import socket #導(dǎo)入模塊 client=socket.socket() #實例初始化 ip_port =("127.0.0.1",8888) #訪問服務(wù)端IP和端口 client.connect(ip_port) #連接sever端 while True: #定義循環(huán),發(fā)送消息 date = client.recv(1024) # 接收sever端信息 print(data.decode()) # 打印接收數(shù)據(jù) msg_input=input("請輸入發(fā)送的信息:") #輸入發(fā)送的信息 client.send(msg_input.encode()) #消息發(fā)送 if msg_input == "exit": #接收到退出命令 break data= client.recv(1024) #接收sever端信息 print(date.decode()) #打印接收的消息
上述是一個客戶端連接服務(wù)器,接下來介紹多個客戶端連接服務(wù)器:
首先對socket參數(shù)進(jìn)行了解:
參數(shù)一:family地址簇
參數(shù)二:type類型
參數(shù)三:proto協(xié)議號
socket UDP通信:
服務(wù)器端:
import socket sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) ip_port = ("127.0.0.1",8888) sk.bind(ip_port) while True: data = sk.recv(1024) print(data.decode()) #bytes--->(decode)--->str
客戶端:
import socket client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) in_port = ("127.0.0.1",8888) while True: msg_input = input("輸入需要發(fā)送的信息:") if msg_input == "exit": break client.sendto(msg_input.encode(),in_port) # str--->(encode)--->bytes client.close()
socket非阻塞模塊:
前面談到的實例程序TCP socket存在阻塞,python能否實現(xiàn)非阻塞TCP通信,顯然是可以的,不然python也不會發(fā)展這么強(qiáng)大。
實現(xiàn)途徑:導(dǎo)入socketsever ,用多線程的方式實現(xiàn)非阻塞——繼承socketsever對象重載setup、handle、finish方法。
import socketserver #定義一個類 class Myserver(socketserver.BaseRequsetHandler): #如果handle方法報錯,則會跳過 #setup和finish方法無論如何都會執(zhí)行 #首先執(zhí)行setup方法 def setup(self): pass #然后執(zhí)行handle方法 def handle(self): #定義連接變量 conn = self.request msg='歡迎來到socket世界' #定義信息 conn.send(msg.encode()) #返回信息 while True: #連續(xù)接受客戶端發(fā)送的消息 data=conn.recv(1024) #接收客戶端信息 print(data.decode()) #打印獲取的數(shù)據(jù),實際開發(fā)生產(chǎn)一般不打印 if data == b'exit': #接收到退出命令 break conn.send(data.encode()) #處理客戶端數(shù)據(jù) conn.send(str(random.randint(1,50000)).encode()) #發(fā)送隨機(jī)數(shù)據(jù)信息 conn.close() #最后執(zhí)行finish方法 def finish(self): pass if name == "__main__": #創(chuàng)建多線程實例 server = socketserver.ThreadingTCPServer((“127.0.0.1",8888),Myserver) #開啟異步多線程,等待連接 server.serve_forever()`
然后用之前的TCP客戶端程序?qū)崿F(xiàn)非阻塞多客戶端通信
實例——文件上傳程序:
運維通常會遇到文件上傳的情況,同時沒有第三方軟件的時候,這個時候我們 可以自己實現(xiàn)文件上傳
文件接收端(server):
import socket sk = socket.socket() ip_port = ("127.0.0.1",9999) sk.bind(ip_port) sk.listen(5) while True: conn,adress = sk.accept() with open("file","ab") as f: #ab可添加二進(jìn)制模式 data = conn.recv(1024) if data == b"exit": break f.write(data) sk.close()
文件發(fā)送端(本機(jī))(client):
import socket #發(fā)起連接 sk = socket.socket() ip_port = ("127.0.0.1", 9999) #服務(wù)器的端口 sk.connect(ip_port) #打開文件 with open(”test.py“,”rb“) as f: for i in f: sk,send(i) sk.send("exit",encode()) #結(jié)束信號
以上所述是小編給大家介紹的Pythony運維入門之Socket網(wǎng)絡(luò)編程詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
- Python 網(wǎng)絡(luò)編程起步(Socket發(fā)送消息)
- Python使用Socket(Https)Post登錄百度的實現(xiàn)代碼
- python socket網(wǎng)絡(luò)編程步驟詳解(socket套接字使用)
- python實現(xiàn)socket端口重定向示例
- python socket 超時設(shè)置 errno 10054
- Python通過websocket與js客戶端通信示例分析
- python網(wǎng)絡(luò)編程學(xué)習(xí)筆記(三):socket網(wǎng)絡(luò)服務(wù)器
- python網(wǎng)絡(luò)編程學(xué)習(xí)筆記(二):socket建立網(wǎng)絡(luò)客戶端
- python網(wǎng)絡(luò)編程之TCP通信實例和socketserver框架使用例子
- 為python設(shè)置socket代理的方法
相關(guān)文章
Python局部函數(shù)及用法詳解(含nonlocal關(guān)鍵字)
局部函數(shù)有哪些特征,在使用時需要注意什么呢?接下來就給讀者詳細(xì)介紹?Python?局部函數(shù)的用法,對Python局部函數(shù)相關(guān)知識感興趣的朋友跟隨小編一起看看吧2022-12-12Python實現(xiàn)簡易版的Web服務(wù)器(推薦)
這篇文章主要介紹了Python實現(xiàn)簡易Web服務(wù)器的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2018-01-01淺談Python數(shù)據(jù)類型判斷及列表腳本操作
下面小編就為大家?guī)硪黄獪\談Python數(shù)據(jù)類型判斷及列表腳本操作。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-11-11Pandas數(shù)據(jù)集的分塊讀取的實現(xiàn)
本文主要介紹了Pandas數(shù)據(jù)集的分塊讀取的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08python中dict獲取關(guān)鍵字與值的實現(xiàn)
這篇文章主要介紹了python中dict獲取關(guān)鍵字與值的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-05-05