Python 中黏包的處理 及實現簡單的ssh

2021-10-04 18:50:34 字數 2837 閱讀 1350

python 中黏包的處理(及實現簡單的ssh)

黏包的處理

首先黏包就是連續傳送兩個資料,且中間沒有阻塞時,作業系統自動將兩次資料打包到一起傳送

黏包的發生會造成資料傳輸後,資料丟失,不完整,接收到資料不能使用

通過阻塞解決黏包問題(影響效率)

通過新增資料長度解決黏包問題(常用解決方式,如下ssh的例項)

ssh的例項

伺服器端**如下:

import socket

import subprocess #使用cmd命令的模組

import struct #壓縮包的模組,將整形數字壓縮成4個位元組

#ret=struct.pack("i",1211)#i為整數模式,最小-2147483648,最大壓縮2147483647,壓縮後為4個位元組

ssh_server = socket.socket(

)ssh_server.bind(

('127.0.0.1'

,8000))

ssh_server.listen(5)

while1:

print

('等待連線'

) conn,addr = ssh_server.accept(

)print

('連線成功'

)while1:

try:

cmd = conn.recv(

1024

).decode(

'gbk'

)#接受客戶端輸入的字串形式的cmd命令

#在伺服器端實現字串形式的cmd命令,並獲取到結果,stderr為錯誤命令結果,stdout為正確命令結果

ret = subprocess.popen(cmd,

shell =

true

, stderr = subprocess.pipe,

stdout = subprocess.pipe,

) err = ret.stderr.read(

)#獲取錯誤命令結果的位元組,(windows預設gbk編碼)

out = ret.stdout.read(

)#獲取正確命令結果的位元組

if err:

#如果錯誤名存在值,說明客戶端輸入的是錯誤的cmd命令,則返回錯誤資訊

print

(len

(err)

)#顯示錯誤資訊位元組長度

len_err = struct.pack(

"i",

len(err)

)#將錯誤資訊位元組長度壓縮成4個位元組

conn.send(len_err)

#發給客戶端要接受的資料長度,方便客戶端接受資料

conn.send(err)

#發給客戶端提示錯誤的資料資訊

else

:print

(len

(out)

)#顯示正確資訊位元組長度

len_out = struct.pack(

"i",

len(out)

)#將正確資訊位元組長度壓縮成4個位元組

conn.send(len_out)

conn.send(out)

#發給客戶端提示錯誤的資料資訊

except exception as e:

print

('連線已斷開'

)break

客戶端**如下:

import socket

import struct

ssh_client = socket.socket(

)ssh_client.connect(

('127.0.0.1'

,8000))

while1:

cmd =

input

('請輸入命令:'

)#輸入字串形式的cmd命令

ssh_client.send(cmd.encode(

'gbk'))

#將字串形式的命令轉換成位元組(windows中cmd編碼預設gbk)

len_data1 = ssh_client.recv(4)

#先接受接下來要接受資料的具體長度

len_data = struct.unpack(

"i",len_data1)[0

]#解壓後獲取int型資料的具體長度

print

(len_data)

#輸出接下來要接受的資料長度

len_res =

0#初始化接受資料總長

res=b""

#初始化接受的資料(位元組)

while len_res < len_data:

#判斷已經獲取的總長是否小於資料總長,如果小於繼續獲取

data = ssh_client.recv(

1024

)#每次接受1024位元組資料

res = res + data#將資料累加到總的資料中

len_res = len_res +

len(data)

#將已經獲取的資料長度累加

print

(res.decode(

'gbk'))

#將獲取的資料解碼輸出

執行的效果圖:

造成黏包的原因,及解決方案

什麼原因導致的黏包?tcp協議的流失傳輸造成的黏包。黏包 自定義協議 先傳送資料長度,再傳送資料。基於tcp先執行乙個遠端行命令的程式 subprocess模組 import subprocess res subprocess.popen dir shell true,終端錯誤 stderr sub...

python中包 python中的包

使用模組可以避免函式名和變數名引發的衝突,那麼如果模組名重複怎麼辦?在python中,提出了包的概念 package 的概念,包是乙個分層次的目錄結構,它將一組功能相近的模組組織在乙個目錄下,這樣既起到了規範 的作用,又能避免模組重名引發的衝突。說明 包簡單的理 解就是 資料夾 只不過是在該資料夾下...

python中的包 python中的包

1.python中的包 包將有聯絡的模組組織在一起,有效避免模組名稱衝突問題,讓應用組織結構更加清晰 假定我們的包的例子有如下的目錄結構 phone init py common util.py voicedta init py pots.py isdn.py fax init py g3.py m...