码迷,mamicode.com
首页 > 其他好文 > 详细

tcp协议黏包问题的解决方式

时间:2019-05-18 17:18:03      阅读:128      评论:0      收藏:0      [点我收藏+]

标签:pip   one   一点   ddr   int   none   close   连续   一个   

# 出现黏包的场景
  # 连续send两个小数据
  # 两个recv,第一个recv特别小
# 本质上:你不知道到底要接受多大的数据

 

# 解决
# 首先:发送一下这个数据到底有多大
# 再按照数据的长度接收数据

#这种解决方式的好处:

  #确定了我到底要接收多大的数据
  #在文件中配置一个配置项:就是每一次recv的大小 buffer=4096
  # 当我们要发送大数据的时候,要明确的告诉接收方要发送多大的数据,以便接收方能够
  # 准确的接收到所有的数据
  # 多在文件的传输过程中
  # 大文件的传输一定是按照字节读,每一次读固定的字节
# 服务端:一边读,一边传 ---------------------- 接收端:一边收,一边写
# send这个大文件之前,40000个字节,send(4096) 40000-4096-4096... -->0以此类推,一点点传
# recv这个大文件之前,recv 40000字节,recv(4096) 40000-4096-4096 -->0以此类推,一点点接

#但是为了不让你发送的数据大小也遇到黏包问题,在此引入struct模块

#以shell命令为例

技术图片
import struct
import socket
sk = socket.socket()
sk.bind((127.0.0.1,8080))
sk.listen(0)

conn,addr = sk.accept()
while True:
    cmd = input(>>>)
    if cmd == q:
        conn.send(bq)
        break
    conn.send(cmd.encode(gbk))
    num = conn.recv(4)
    num = struct.unpack(i,num)[0]
    res = conn.recv(int(num)).decode(gbk)
    print(res)
conn.close()
sk.close()
server
技术图片
import socket
import subprocess
import struct
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()
    len_num = len(std_err)+len(std_out)
    num_by = struct.pack(i,len_num)
    sk.send(num_by)
    sk.send(std_out)
    sk.send(std_err)
sk.close()
client

 

tcp协议黏包问题的解决方式

标签:pip   one   一点   ddr   int   none   close   连续   一个   

原文地址:https://www.cnblogs.com/Mr-Feng/p/10886337.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!