Python--网络编程-----解决粘包问题-简单版

一、服务端代码为:

 1 import socket
 2 import subprocess
 3 import struct
 4 
 5 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 6 # phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 7 phone.bind(('127.0.0.1', 8081))  # 0-65535:0-1024给操作系统使用
 8 phone.listen(5)
 9 
10 print('starting......')
11 while True:  # 链接循环
12     conn, client_addr = phone.accept()
13     print(client_addr)
14 
15     while True:  # 通信循环
16         try:
17             # 1、收命令
18             cmd = conn.recv(1024)
19             if not cmd:  # 适用于linux操作系统
20                 break
21             print('客户端的数据', cmd)
22 
23             # 2、执行命令,拿到结果
24             obj = subprocess.Popen(cmd.decode('utf-8'), shell=True,
25                                    stdout=subprocess.PIPE,
26                                    stderr=subprocess.PIPE)
27 
28             stdout = obj.stdout.read()
29             stderr = obj.stderr.read()
30             # 3、把命令的结果返回给客户端
31             # 第一步:制作固定长度的报头
32             total_size = len(stdout) + len(stderr)
33             header = struct.pack('i', total_size)
34 
35             # 第二步:把包头发送给客户端
36             conn.send(header)
37 
38             # 第三步:再发送真实的数据
39             conn.send(stdout)
40             conn.send(stderr)
41 
42         except ConnectionResetError:  # 适用于Windows操作系统
43             break
44 
45     conn.close()
46 
47 phone.close()

二、客户端代码为:

 1 import socket
 2 import struct
 3 
 4 
 5 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 6 
 7 phone.connect(('127.0.0.1', 8081))
 8 
 9 while True:
10     # 1、发命令
11     cmd = input('>>:').strip()
12     if not cmd:
13         continue
14     phone.send(cmd.encode('utf-8'))
15 
16     # 2、拿命令的结果,并打印
17 
18     # 第一步:先收报头
19     header = phone.recv(4)
20 
21     # 第二步:从报头中解析出对真实数据的描述信息(数据的长度)
22     total_size = struct.unpack('i', header)[0]
23 
24     # 第三步: 接收真实的数据
25     recv_size = 0
26     recv_data = b''
27     while recv_size < total_size:
28         res = phone.recv(1024)  # 1024是一个坑
29         recv_data += res
30         recv_size += len(res)
31     print(recv_data.decode('gbk'))
32 
33 phone.close()

在客户端依次输入,dir, ipconfig, dir,客户端结果为:

 1 >>:dir
 2  驱动器 C 中的卷是 OS
 3  卷的序列号是 7849-BAF9
 4 
 5  C:Usersxu516PycharmProjectsPython全栈开发第三模块网络编程5 解决粘包问题简单版 的目录
 6 
 7 2018/04/08  21:48    <DIR>          .
 8 2018/04/08  21:48    <DIR>          ..
 9 2018/04/08  21:40               128 struct模块的使用.py
10 2018/04/08  21:48               802 客户端.py
11 2018/04/08  21:48             1,487 服务端.py
12                3 个文件          2,417 字节
13                2 个目录 36,977,733,632 可用字节
14 
15 >>:ipconfig
16 
17 Windows IP 配置
18 
19 
20 无线局域网适配器 本地连接* 3:
21 
22    媒体状态  . . . . . . . . . . . . : 媒体已断开连接
23    连接特定的 DNS 后缀 . . . . . . . : 
24 
25 以太网适配器 VMware Network Adapter VMnet1:
26 
27    连接特定的 DNS 后缀 . . . . . . . : 
28    本地链接 IPv6 地址. . . . . . . . : fe80::5d54:4c1:d7d6:c647%6
29    IPv4 地址 . . . . . . . . . . . . : 192.168.189.1
30    子网掩码  . . . . . . . . . . . . : 255.255.255.0
31    默认网关. . . . . . . . . . . . . : 
32 
33 以太网适配器 VMware Network Adapter VMnet8:
34 
35    连接特定的 DNS 后缀 . . . . . . . : 
36    本地链接 IPv6 地址. . . . . . . . : fe80::680e:7f79:aed1:fe62%10
37    IPv4 地址 . . . . . . . . . . . . : 192.168.254.1
38    子网掩码  . . . . . . . . . . . . : 255.255.255.0
39    默认网关. . . . . . . . . . . . . : 
40 
41 无线局域网适配器 WLAN:
42 
43    连接特定的 DNS 后缀 . . . . . . . : DHCP HOST
44    本地链接 IPv6 地址. . . . . . . . : fe80::9c84:419c:e3af:89dd%11
45    IPv4 地址 . . . . . . . . . . . . : 192.168.0.106
46    子网掩码  . . . . . . . . . . . . : 255.255.255.0
47    默认网关. . . . . . . . . . . . . : 192.168.0.1
48 
49 以太网适配器 蓝牙网络连接:
50 
51    媒体状态  . . . . . . . . . . . . : 媒体已断开连接
52    连接特定的 DNS 后缀 . . . . . . . : 
53 
54 隧道适配器 Teredo Tunneling Pseudo-Interface:
55 
56    连接特定的 DNS 后缀 . . . . . . . : 
57    IPv6 地址 . . . . . . . . . . . . : 2001:0:9d38:953c:20d3:83ef:d86a:f024
58    本地链接 IPv6 地址. . . . . . . . : fe80::20d3:83ef:d86a:f024%2
59    默认网关. . . . . . . . . . . . . : ::
60 
61 >>:dir
62  驱动器 C 中的卷是 OS
63  卷的序列号是 7849-BAF9
64 
65  C:Usersxu516PycharmProjectsPython全栈开发第三模块网络编程5 解决粘包问题简单版 的目录
66 
67 2018/04/08  21:48    <DIR>          .
68 2018/04/08  21:48    <DIR>          ..
69 2018/04/08  21:40               128 struct模块的使用.py
70 2018/04/08  21:48               802 客户端.py
71 2018/04/08  21:48             1,487 服务端.py
72                3 个文件          2,417 字节
73                2 个目录 36,977,725,440 可用字节
74 
75 >>:

从以上客户端输出结果可以看出,解决了粘包现象

原文地址:https://www.cnblogs.com/xudachen/p/8747755.html