Python socket網路程式設計4

2021-08-02 23:00:23 字數 4881 閱讀 3500

python網路程式設計傳送資料時可以用struct.pack將字元編碼的長度打包 然後當做報頭髮送過去

此方法適用於檔案不大時 或者簡單命令傳送  參考github  

比較複雜的大資料.可以使用字典 json傳過去 

以下為示例**

#!/usr/bin/env python

# -*- coding:utf-8 -*-

'''socket2 高階'''

'''接上節內容 處理粘包問題 此處更改了報頭,使用了字典

'''import socket,json

import subprocess,struct

phone=socket.socket(socket.af_inet,socket.sock_stream) #理解為買**.基於ipv4 基於流式協議tcp sock_dgram udp協議

phone.setsockopt(socket.sol_socket,socket.so_reuseaddr,1) #注釋5 重用ip位址

phone.bind(('127.0.0.1',8080)) #插卡

while true: #注釋3

conn,addr=phone.accept()#等待**接通 conn建好的連線 addr客戶端位址

while true: #注釋1

try: #注釋2

cmd=conn.recv(1024) #開始接收訊息 此處先使用1024 每次接收的大小

if not cmd:break #注釋4

'''執行命令,獲取正確輸入和錯誤輸入

如果有錯誤輸出則輸出錯誤

否則輸出正確解決(此處正確結果為和系統相關的編碼格式,此處為gbk)'''

res=subprocess.popen(cmd.decode('utf-8'),shell=true,

stdout=subprocess.pipe,

stderr=subprocess.pipe,)

err=res.stderr.read()

if err:

cmd_res=err

else:

cmd_res=res.stdout.read()

#conn.send(struct.pack('i',len(cmd_res)))

'''改用字典方式'''

head_dic=

head_json=json.dumps(head_dic)

head_bytes=head_json.encode('utf-8')

'''先傳送json的報頭'''

conn.send(struct.pack('i',len(head_bytes)))

conn.send(head_bytes)

conn.send(cmd_res)

except connectionreseterror: #exception 萬能捕獲異常

break

conn.close() #關閉連線

phone.close() #關閉手機

以下為客戶端資訊

#!/usr/bin/env python

# -*- coding:utf-8 -*-

''''''

'''此處接收分段 先接收大小 然後分段接收資料

'''import socket,struct,json

phone=socket.socket(socket.af_inet,socket.sock_stream) #等同於服務端

phone.connect(('127.0.0.1',8080)) #撥通** 注意此處是乙個元組的形式

while true:

cmd=input('>>:').strip()

if not cmd:continue

phone.send(cmd.encode('utf-8')) #轉為二進位制發出去

print('ready to recv message')

'''先收報頭的長度'''

head_struct = phone.recv(4)

head_len = struct.unpack('i',head_struct)[0]

head_bytes = phone.recv(head_len)

head_json = head_bytes.decode('utf-8')

head_dic = json.loads(head_json)

'''根據報頭里的詳細資訊,取真實的資料'''

total_size = head_dic['total_size']

recv_size=0

data=b''

while recv_size < total_size:

recv_data=phone.recv(1024)

data+=recv_data

recv_size+=len(recv_data)

print(data.decode('gbk'))

phone.close()

附加舊版本的socket優化

優化每次位元組先打包傳送

server端內容

#!/usr/bin/env python

# -*- coding:utf-8 -*-

'''socket2 高階'''

'''接上節內容 處理粘包問題

''''''

此處接上節內容 , 擴充套件支援往服務端傳送命令. 並返回執行結果. 模擬xshell的執行方式

''''''

1.使用while true 實現客戶端服務端迴圈通訊

2.異常捕獲處理客戶端異常關閉導致的崩潰 , 針對windows系統下

3.再次新增while true 實現迴圈建立連線

4.客戶端無訊息斷開連線 , 針對linux系統下

5.此處有出現斷開占用問題(egon blog) 可以修改核心引數或者在繫結位址之前判斷

'''import socket

import subprocess,struct

phone=socket.socket(socket.af_inet,socket.sock_stream) #理解為買**.基於ipv4 基於流式協議tcp sock_dgram udp協議

phone.setsockopt(socket.sol_socket,socket.so_reuseaddr,1) #注釋5 重用ip位址

phone.bind(('127.0.0.1',8080)) #插卡

while true: #注釋3

conn,addr=phone.accept()#等待**接通 conn建好的連線 addr客戶端位址

while true: #注釋1

try: #注釋2

cmd=conn.recv(1024) #開始接收訊息 此處先使用1024 每次接收的大小

if not cmd:break #注釋4

'''執行命令,獲取正確輸入和錯誤輸入

如果有錯誤輸出則輸出錯誤

否則輸出正確解決(此處正確結果為和系統相關的編碼格式,此處為gbk)'''

res=subprocess.popen(cmd.decode('utf-8'),shell=true,

stdout=subprocess.pipe,

stderr=subprocess.pipe,)

err=res.stderr.read()

if err:

cmd_res=err

else:

cmd_res=res.stdout.read()

conn.send(struct.pack('i',len(cmd_res)))

conn.send(cmd_res)

except connectionreseterror: #exception 萬能捕獲異常

break

conn.close() #關閉連線

phone.close() #關閉手機

client端內容

#!/usr/bin/env python

# -*- coding:utf-8 -*-

''''''

'''此處接收分段 先接收大小 然後分段接收資料

'''import socket,struct

phone=socket.socket(socket.af_inet,socket.sock_stream) #等同於服務端

phone.connect(('127.0.0.1',8080)) #撥通** 注意此處是乙個元組的形式

while true:

cmd=input('>>:').strip()

if not cmd:continue

phone.send(cmd.encode('utf-8')) #轉為二進位制發出去

print('ready to recv message')

head=phone.recv(4)

total_size=struct.unpack('i',head)[0]

#cmd_msg=phone.recv(total_size)

recv_size=0

data=b''

while recv_size < total_size:

recv_data=phone.recv(1024) #進行分段接收 優化資料過大問題

data+=recv_data

recv_size+=len(recv_data)

print(data.decode('gbk'))

phone.close()

Python Socket 網路程式設計

socket 是程序間通訊的一種方式,它與其他程序間通訊的乙個主要不同是 它能實現不同主機間的程序間通訊,我們網路上各種各樣的服務大多都是基於 socket 來完成通訊的,例如我們每天瀏覽網頁 qq 聊天 收發 email 等等。要解決網路上兩台主機之間的程序通訊問題,首先要唯一標識該程序,在 tc...

python socket網路程式設計

s.getsockname 獲得本地機器的ip和埠號 埠號由作業系統隨機分配,每次都不一樣 17 print conneted to s.getpeername 獲得連線機器的ip和埠號 結果如下 creating socketdone looking up port number.80doneco...

Python socket網路程式設計

socket簡單介紹 author xuefeng ipconfig all 檢視ip位址與mac 物理 位址 import socket socket family 位址簇 socket.af unix 本機兩個程序之間進行通訊 socket.af inet ipv4 socket.af inet...