32、黏包的解決方式、struct模塊
阿新 • • 發佈:2018-02-04
大數 總量 接收 多少 rec 能夠 文件的 sendto while
黏包的解決方式
黏包出現的根本原因是接收方不知道要傳過來多少數據,解決方法1:在傳給接收方以前告訴它要傳過去多少數據。 解決方法2:使用struct方法
解決方法1:傳之前告訴它要傳多少
#服務器端 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‘) # 2048 conn.send(b‘ok‘) res = conn.recv(int(num)).decode(‘gbk‘) print(res) conn.close() sk.close()
#客戶端 import socket import subprocess sk = socket.socket() sk.connect((‘127.0.0.1‘,8080)) while True: cmd = sk.recv(1024).decode(‘gbk‘)if cmd == ‘q‘: break res = subprocess.Popen(cmd,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) std_out = res.stdout.read() std_err = res.stderr.read() sk.send(str(len(std_out)+len(std_err)).encode(‘utf-8‘)) #2000 sk.recv(1024) #ok sk.send(std_out) sk.send(std_err) sk.close()
這種方法的好處:確定了我要接收多大的值
1)要在文件中配置一個配置項:就是每一次recv的大小
2)當我們要發送大數據的時候,要明確的告訴接收方要發送多大的數據,以便接收方能夠準確接收所有的數據。
3)用處:多用在文件傳輸的過程中
1、大文件的傳輸一定是按照字節讀,每一次讀固定的字節
2、傳輸的過程中,一邊讀一邊傳,接收端一邊收一邊寫
3、send這個大文件之前,每一次文件總量減去固定值
4、recv這個大文件,每一次接收之後減去固定值
這種方法的不好的地方:多了一次交互
1)send\sendto,在超過一定範圍的時候就會報錯
2)程序的內存管理(啥意思???)
解決方法二:用struct將文件大小或者長度轉化成4個字節的bytes類型
import socket import subprocess import struct #接收命令 sk=socket.socket() sk.connect((‘127.0.0.1‘,8008)) while True: cmd=sk.recv(1024).decode(‘gbk‘) ret=subprocess.Popen(cmd,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) std_out=ret.stdout.read() std_err=ret.stderr.read() len_std=len(st_out)+len(std_err) len_num=struct.pack(‘i‘,len_std) #將執行命令後的內容長度轉化成4個字節類型 sk.send(len_num) sk.send(std_out) sk.send(std_err) sk.close()
#客戶端 import socket import struct sk=socket.socket() sk.bind((‘127.0.0.1‘,8008)) sk.listen() con,addr=sk.accept() while True: cmd=input(‘>>>‘) con.send(cmd.encode(‘gbk‘)) num=con.recv(4) len_by=struct.unpack(‘i‘,num)[0] #接收到的4個字節長度轉化成數字,重點!!! ret=con.recv(len_by).decode(‘gbk‘) print(ret) con.close() sk.close()
32、黏包的解決方式、struct模塊