網路程式設計筆記 3 解決黏包問題

2022-09-17 22:51:24 字數 2974 閱讀 7631

優點:

缺點:注意:

# server端:

import socket

sk = socket.socket()

sk.bind(('127.0.0.1',8080))

sk.listen()

conn,addr = sk.accept()

while true:

cmd = input('>>>')

if cmd == 'q':

conn.send(b'q')

break

conn.send(cmd.encode('gbk'))

num = conn.recv(1024).decode('utf-8') #接收到了client端發過來的位元組總數

conn.send(b'ok')

res = conn.recv(int(num)).decode('gbk') #獲取了接收的總位元組數,設定進要接收的值裡面,就可以動態的感知要傳送的資料了

print(res)

conn.close()

sk.close()

#client端:

import socket

import subprocess

sk = socket.socket()

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

while true:

cmd = sk.recv(1024).decode('gbk') #因為windows傳輸都為gbk編碼的

if cmd == 'q':

break

res = subprocess.popen(cmd,shell=true, #pipe為管道/佇列,只能取一次,取完就結束了

stdout=subprocess.pipe, #stdout為命令的輸出

stderr=subprocess.pipe) #stderr為命令錯誤的提示資訊

std_out = res.stdout.read() #從佇列中取出命令

std_err = res.stderr.read() #從佇列中取出錯誤命令資訊

sk.send(str(len(std_out)+len(std_err)).encode('utf-8')) #計算要傳送的位元組總數並傳送過去

sk.recv(4096) #一般不要超過這個數字,否則會超過裝置記憶體

sk.send(std_out)

sk.send(std_err)

sk.close()

#傳送端需要借助struct模組

import struct

ret = struct.pack('i',2048) #'i'代表int,就是即將要把乙個數字轉換成固定長度的bytes型別

print(ret)

#接收端:

num = struct.unpack('i',ret) #此時num為元組tuple型別

print(num[0]) #獲取資料長度2048

#這樣接收方只需要接收固定的長度就可以獲取整個資料的長度了

# 使用struct模組收發資訊

# server端:

import socket

import struct

sk = socket.socket()

sk.bind(('127.0.0.1',8080))

sk.listen()

conn,addr = sk.accept()

while true:

cmd = input('>>>')

if cmd == 'q':

conn.send(b'q')

break

conn.send(cmd.encode('gbk'))

num = conn.recv(4) #接收到了client端發過來的4個位元組數(二進位制),不管多大始終是4個位元組

num = struct.unpack('i',num)[0] #把4個位元組數二進位制unpack,得到總位元組數:num

res = conn.recv(int(num)).decode('gbk') #獲取了接收的總位元組數,設定進要接收的值裡面,就可以動態的感知要傳送的資料了

print(res)

conn.close()

sk.close()

# client端:

import socket

import struct

import subprocess

sk = socket.socket()

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

while true:

cmd = sk.recv(1024).decode('gbk') #因為windows傳輸都為gbk編碼的

if cmd == 'q':

break

res = subprocess.popen(cmd,shell=true, #pipe為管道/佇列,只能取一次,取完就結束了

stdout=subprocess.pipe, #stdout為命令的輸出

stderr=subprocess.pipe) #stderr為命令錯誤的提示資訊

std_out = res.stdout.read() #從佇列中取出命令

std_err = res.stderr.read() #從佇列中取出錯誤命令資訊

len_num = len(std_out) + len(std_err)#計算要傳送的位元組總數並傳送過去

num_by = struct.pack('i',len_num) #使用模組pack進去總位元組數,傳送過去的始終是4個位元組

sk.send(num_by) #傳送了4個位元組

sk.send(std_out)

sk.send(std_err)

sk.close()

網路程式設計 黏包現象(五)

一 黏包現象 大檔案一般用tcp,udp雖不黏包但不可靠 不宜傳送大檔案 二 1 server端 不知道客戶端傳送的資料長度 print data1.decode utf 8 print data2.decode utf 8 import time time.sleep 1 data2 conn.r...

day29 struct模組解決黏包問題

struct模組可以把乙個資料型別,例如數字int,轉化成固定長度 4個位元組 的bytes。int轉為4個bytes。在大量傳輸資料之前先告訴接收端即將接收資料的大小,方可解決黏包問題 利用struct模組打包要傳送的資料的長度,接收端接收這個包,解包之後,接收這個長度的資料。import str...

python網路程式設計 粘包問題的解決

我們使用tcp協議的時候有時會出現一些問題,就比如我同時傳送了3次資料,但是在另外一邊缺只收到了一次,它把三次資料都和在了一起,import socket server socket.socket server.bind 127.0.0.1 18080 繫結ip和埠 server.listen 2 ...