Python之旅Day8 socket网络编程
生活随笔
收集整理的這篇文章主要介紹了
Python之旅Day8 socket网络编程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
socket網絡編程
Socket是網絡編程的一個抽象概念。通常我們用一個Socket表示“打開了一個網絡鏈接”,而打開一個Socket需要知道目標計算機的IP地址和端口號,再指定協議類型即可。socket服務一般分為服務端和客戶端;與此同時,socket服務有基本tcp和udp的兩種版本類型
?
TCP類型
基礎版socket服務
####服務端#### import socket phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)#買手機 '''AF_INET:地址家族; SOCK_STREAM:TCP協議'''phone.bind(('127.0.0.1',8080))#插卡 phone.listen(5) #開機(監聽) '''listen(5):等待客戶端連接的最大連接數(可自定義數值)'''conn,addr=phone.accept()#接電話(3次握手建立連接) print('tcp的連接',conn) print('客戶端的地址',addr)data = conn.recv(1024) #說話(收消息) print('from client msg: %s' %data)conn.send(data.upper()) #發消息 conn.close()#掛電話 phone.close()#關手機####客戶端#### import socket client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) '''AF_INET:地址家族; SOCK_STREAM:TCP協議'''client.connect(('127.0.0.1',8080)) #撥通電話 client.send('hello'.encode('utf-8')) #客戶端發消息 data = client.recv(1024) #客戶端收消息 print(data) client.close() #關閉?
循環版socket服務
####服務端#### import socket phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)#買手機 '''AF_INET:地址家族; SOCK_STREAM:TCP協議'''phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) '''用來解決報錯:ConnectionResetError: [WinError 10054] 遠程主機強迫關閉了一個現有的連接。'''phone.bind(('127.0.0.1',8080))#插卡 phone.listen(5) #開機(監聽) '''listen(5):等待客戶端連接的最大連接數(可自定義數值)'''while True: #鏈接循環conn,addr=phone.accept()#接電話(3次握手建立連接)print('client: ',addr)while True: #通訊循環try:data = conn.recv(1024) #說話(收消息)if not data:break #針對Linux,客戶端斷開鏈接的異常處理print('from client msg: %s' %data)conn.send(data.upper()) #發消息except Exception: #異常捕捉breakconn.close()#掛電話 phone.close()#關手機####客戶端#### import socket client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) '''AF_INET:地址家族; SOCK_STREAM:TCP協議'''client.connect(('127.0.0.1',8080)) #撥通電話while True:msg = input('>>>: ')if not msg:continueclient.send(msg.encode('utf-8')) #客戶端發消息 data = client.recv(1024) #客戶端收消息print(data)client.close() #關閉?
socketserver服務(可并發的socket)
####服務端#### import socketserverclass FtpServer(socketserver.BaseRequestHandler):def handle(self):print(self.request) #connprint(self.client_address)while True:data = self.request.recv(1024)self.request.send(data.upper())if __name__ == '__main__':s = socketserver.ThreadingTCPServer(('127.0.0.1',8080),FtpServer)s.serve_forever() #鏈接循環就有了####客戶端1#### # import socket from socket import *client = socket(AF_INET,SOCK_STREAM) client.connect(('127.0.0.1',8080))while True:msg = input('>>: ')client.send(msg.encode('utf-8'))data = client.recv(1024)print(data)####客戶端1#### # import socket from socket import *client = socket(AF_INET,SOCK_STREAM) client.connect(('127.0.0.1',8080))while True:msg = input('>>: ')client.send(msg.encode('utf-8'))data = client.recv(1024)print(data)""" socketserver可以實現多并發,即一個服務端同時和多個客戶端進行通信 """?
遠程執行
###遠程執行命令-server端### import socket import subprocess import struct import jsonphone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)#買手機 '''AF_INET:地址家族; SOCK_STREAM:TCP協議'''phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) '''用來解決報錯:ConnectionResetError: [WinError 10054] 遠程主機強迫關閉了一個現有的連接。'''phone.bind(('127.0.0.1',8080))#插卡 phone.listen(5) #開機(監聽) '''listen(5):等待客戶端連接的最大連接數(可自定義數值)'''while True: #鏈接循環conn,addr=phone.accept()#接電話(3次握手建立連接)print('client: ',addr)while True: #通訊循環try:cmd = conn.recv(1024) #說話(收消息)if not cmd:break #針對Linux,客戶端斷開鏈接的異常處理print('from client msg: %s' %cmd)res = subprocess.Popen(cmd.decode('utf-8'),shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)err = res.stderr.read()if err:back_msg = errelse:back_msg = res.stdout.read()#解決長度局限#第一階段:制作報頭head_dic = {'data_size':len(back_msg)}head_json = json.dumps(head_dic)head_bytes = head_json.encode('utf-8')'''添加解決粘包代碼'''# conn.send(struct.pack('i',len(back_msg))) #傳數據的長度(有局限)#第二階段:發送報頭的長度conn.send(struct.pack('i',len(head_bytes)))# conn.send(back_msg)# 第三階段:發報頭 conn.send(head_bytes)#第四階段:發真實數據 conn.sendall(back_msg)except Exception: #異常捕捉breakconn.close()#掛電話 phone.close()#關手機###遠程執行命令-client端### import socket import struct import jsonclient = socket.socket(socket.AF_INET,socket.SOCK_STREAM) client.connect(('127.0.0.1',8080))while True:cmd= input('>>>: ').strip()if not cmd:continueclient.send(cmd.encode('utf-8'))#解決粘包注釋的改動部分(注釋掉)# res=client.recv(1024)# print(res.decode('gbk'))'''通過定義傳輸數據文件大小來解決粘包'''# data = client.recv(4)# data_size=struct.unpack('i',data)[0]###優化:接收頭的長度head = client.recv(4)head_size = struct.unpack('i',head)[0]###收報頭(根據報頭長度)head_bytes = client.recv(head_size)head_json = head_bytes.decode('utf-8')head_dic= json.loads(head_json)data_size = head_dic['data_size'] #取真實數據"""大數據量傳輸(收真實數據)"""recv_size = 0recv_bytes = b''while recv_size < data_size:res=client.recv(1024)recv_bytes+=resrecv_size+=len(res)print(recv_bytes.decode('gbk'))# res=client.recv(data_size)# print(res.decode('gbk'))?
轉載于:https://www.cnblogs.com/wuchunwei/p/7239815.html
總結
以上是生活随笔為你收集整理的Python之旅Day8 socket网络编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: redis 类型、方法
- 下一篇: python 替换字符串