zoukankan      html  css  js  c++  java
  • 四、tcp中的粘包问题解决

    • 粘包问题

      • tcp是流式协议,数据像水流一样粘在一起,没有任何边界区分

      • 收数据没收干净

      粘包解决思路

      • 每次都收干净,不要任何残留

      粘包解决办法

      • 利用好struct模块

        服务端

        • 通过struct这个模块,构造固定长度的数据包头信息,接着才发送数据,即自定义的协议

        • 代码

          import socket
          import struct
          import subprocess

          server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
          server.bind(("127.0.0.1", 8080))
          server.listen(5)

          while True:
             client, client_addr = server.accept()
             while True:
                 try:
                     recv_msg = client.recv(1024)
                     if len(recv_msg) == 0:
                         break
                     obj = subprocess.Popen(recv_msg.decode('utf8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                     stdout_res = obj.stdout.read()
                     stderr_res = obj.stderr.read()
                     total_size = len(stdout_res) + len(stderr_res)
                     # 发送固定长度的header
                     header = struct.pack('i', total_size)
                     client.send(header)
                     # 发送data
                     client.send(stdout_res)
                     client.send(stderr_res)
                 except Exception:
                     pass
             client.close()

        客户端

        • 先收固定长度的头:解析出数据的描述信息,包括数据的总大小total_size

        • recv_size=0在循环接收data后累加

        • 当recv_size=total_size循环接收结束

        • 代码

          import socket
          import struct

          client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

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

          while True:
             msg = input("请输入命令>>:").strip()
             if len(msg) == 0:
                 continue
             client.send(msg.encode('utf-8'))
             # 接受头信息
             header = client.recv(4)
             total_size = struct.unpack("i", header)[0]
             current_size = 0
             # 循环接收data
             while current_size < total_size:
                 recv_data = client.recv(1024)
                 current_size += len(recv_data)
                 print(recv_data.decode("utf-8"))
             else:
                 print()
  • 相关阅读:
    软件工程问题清单
    问题清单
    2020软件工程3作业
    2020软件工程作业02
    2020软件工程作业01
    2020软件工程个人作业06——软件工程实践总结作业
    2020软件工程作业03
    2020软件工程作业05
    软件工程作业 疑问总结
    2020软件工程作业04
  • 原文地址:https://www.cnblogs.com/nuochengze/p/13342110.html
Copyright © 2011-2022 走看看