tcp套接字ssh遠端命令和解決粘包

2021-08-21 08:29:37 字數 2726 閱讀 5438

粘包問題

描述:接收到傳來的資料過大時,會殘留資料,下次軟體會在作業系統拿到上次遺留的資料就為粘包問題

tcp協議的nagle演算法會將資料量較小,並且傳送時間間隔較短的多個資料合在一起發

解決辦法

自定義報頭

服務端from socket import * #優化**

import subprocess

import struct  #pack將整型的數字轉換成固定長度的bytes型別 unpick則相反

import json

server=socket(af_inet,sock_stream)  #建立服務端物件,用tcp

server.bind(('127.0.0.1',8080))   #繫結埠

server.listen(5) #半連線池同時請求數

while true:

conn,client_addr=server.accept() #建立與客戶端鏈結

print('新的客戶端',client_addr)

while true:

try:

cmd=conn.recv(1024) #cmd=b'dir'為bytes型別

if len(cmd) == 0:break #出現客戶端斷開時解決方案

# 執行系統命令

obj=subprocess.popen(cmd.decode('utf-8'),#要為字串型別

shell=true,

stderr=subprocess.pipe,#錯誤結果

stdout=subprocess.pipe#正確結果

)stdout=obj.stdout.read()#得到的結果為bytes,windows執行為gbk

stderr=obj.stderr.read()

#先製作報頭

header_dic=

header_json=json.dumps(header_dic) #得到的結果為字串型別

header_bytes=header_json.encode('utf-8')#轉換為bytes傳送

#1、先把報頭的長度len(header_bytes)打包成4個bytes,然後傳送

conn.send(struct.pack('i',len(header_bytes)))  #報頭長度固定,用i格式

#2、傳送報頭

conn.send(header_bytes)

#3、再傳送真實的資料

conn.send(stdout)

conn.send(stderr)

except connectionreseterror:

break

conn.close()

客戶端from socket import *

import struct

import json

client=socket(af_inet,sock_stream)

client.connect(('127.0.0.1',8080))

while true:

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

if len(cmd) == 0:continue

client.send(cmd.encode('utf-8'))

#1、先收4個位元組,該4個位元組中包含報頭的長度

header_len=struct.unpack('i',client.recv(4))[0] #uupack的結果為只有乙個值的元組,取第乙個值,為傳來資料的bytes長度。

# 將收到bytes型別解析成元組

#2、再接收報頭

header_bytes=client.recv(header_len) #收到序列化的bytes資料

#從報頭中解析出想要的內容

header_json=header_bytes.decode('utf-8')#將bytes型別轉換成字串

header_dic=json.loads(header_json) #反序列化出訪問的字典

print(header_dic)

total_size=header_dic['total_size'] #拿到服務端發過來真實的資料bytes的總長度

#3、再收真實的資料

recv_size=0 #定義變數,接受位元組長度的初始值

res=b''   #接收到的資料初始值

while recv_size < total_size : #小於所有的資料長度繼續迴圈

data=client.recv(1024)  #1024變成更大跟快取有關,且不合理,最大為8096

res+=data

recv_size+=len(data)  #date為實際接收到的資料

print(res.decode('gbk')) #通過解碼列印資料

struct 模組的運用

import struct

import json

header_dic=

header_json=json.dumps(header_dic)

header_bytes=header_json.encode('utf-8') #把str型別轉成bytes型別

obj=struct.pack('i',len(header_bytes)) #固定報頭長度

print(obj,len(obj))

## res=struct.unpack('i',header)

# print(res[0])#讀出的為元組,第乙個值為報頭長度

TCP的套接字

摘自 深入理解計算機網路 王達著 機械工業出版社 1.ipv4資料報頭部格式 2.ipv6資料報頭部格式 3.ipv4資料報的封裝與解封裝 4.ipv4資料報的分段與重組 5.arp協議報文格式及arp表 6.arp位址解析原理 7.icmp協議及報文格式 8.ipv6協議族的其它協議 9.tcp的...

TCP套接字程式設計

網路程式設計又稱為套接字程式設計,為了與遠端計算機進行資料傳輸,需要連線到網際網路,而程式設計中的 套接字 就是用來連線該網路的工具。它本身具有連線的含義,還可以表示為兩台計算機之間的網路連線。4.呼叫accept函式受理連線請求 基於tcp的服務端 客戶端 tcp伺服器端預設函式呼叫順序 sock...

TCP套接字程式設計

對於socket不理解的可以檢視 c語言通過socket程式設計實現tcp通訊,linux socket程式設計 socket詳解 先看看程式效果圖 提示如果伺服器,直接通過ctrl z關閉,這樣程式占用的位址不會釋放,需要以下操作 1.ps 檢視程序 2.kill 9 程式pid 強制殺死程序 服...