什么是黏包问题:

  首先黏包问题只会在基于TCP协议的socket编程中出现,出现的原因是:由于TCP是字节流协议,客户端在接受服务短发来的数据时,会把数据组织成数据流接收。若客户端的socket对象调用的recv(size)方法中的size值大于或小于服务端发送的数据的长度,都会使多个数据包合成一个包传送,造成数据的混乱,从而形成黏包。

  解决方法是:自定义报头。中心思想是:服务端定制报头(对发送数据的描述信息),服务端在发送真正的数据之前,先向客户端发送报头,客户端接受到报头之后,先读取报头的内容,让客户端知道数据的长度,从而指定自身recv()方法中size的大小,解决黏包问题。

代码示例1:

 1 import   socket
 2 import subprocess
 3 import json
 4 import struct
 5 server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 6 ip_port = ('127.0.0.1',8855)
 7 server.bind(ip_port)
 8 server.listen(5)
 9 while True:
10     con,add = server.accept()
11     print(con)
12     print(add)
13     while True:
14         try:
15             data_bytes = con.recv(1024)
16             if not data_bytes:break
17             cmd = subprocess.Popen(data_bytes.decode('utf-8'),shell=True,
18                                    stdout=subprocess.PIPE,
19                                    stderr=subprocess.PIPE)
20             #从管道读出的数据都是bytes类型,因此在发送到客户端时不需要编码
21             std_out =  cmd.stdout.read()
22             std_err =  cmd.stderr.read()
23             data_size = len(std_out) + len(std_err)
24             #定制报头
25             head_dic = {'data_size':data_size}
26             # 报头处理
27             head_str = json.dumps(head_dic)
28             head_bytes = head_str.encode('utf-8')
29             head_len = len(head_str)
30             head_size = struct.pack('i',head_len)
31             # 发送报头长度(发送4个字节)
32             con.send(head_size)
33             #发送报头数据
34             con.send(head_bytes)
35             # 发送数据
36             con.send(std_out)
37             con.send(std_err)
38         except Exception:
39             break
40     con.close()
41 server.close()
服务端

相关文章:

  • 2021-09-10
  • 2021-05-06
  • 2021-05-01
  • 2021-10-04
  • 2022-12-23
  • 2022-01-01
猜你喜欢
  • 2021-10-18
  • 2022-12-23
  • 2021-09-08
相关资源
相似解决方案