服务端
结束调试的程序
linux
pkill -9 python
windows
taskkill python
解决粘包问题
思路:在接受数据之前先告知要接受的数据的长度
发送的数据包括报头和真实数据
在发送报头前用固定长度的字节告知报头的长度,
接着在报头中包含真实数据的信息和真实数据的字节长度
发送端
制作报头
data = '这是真实数据'.encode()
header_dict = {
'filename': 'xxxx',
'md5':'xxxx',
'total_size': len(data), # 告知真实数据的长度
}
使用json模块做序列化
import json
header_str = json.dumps(header_dict)
header_bytes = header_str.encode()
header_len = len(header_bytes)
使用struct模块将整数打包为固定字节长度
import struct
header_len_pack = struct.pack('i', header_len) # 将整数打包成固定4字节长度的编码
按顺序,先发报头长度,再发报头,最后发送真实数据
conn.send(header_len_pack)
conn.send(header_bytes)
conn.send(data)
接收端
先接收报头长度
import struct
header_len = struct.unpack('i', client.recv(4))[0]
接收报头
import json
header = json.loads(client.recv(header_len))
根据报头提示接收真实数据
total_len = header['total_len']
recv_len = 0
recv_data = ''
while recv_len < total_len:
rec = client.recv(1024)
recv_data += rec
recv_len += len(rec)
import socket
import subprocess
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 若出现端口占用则重用这个端口
# 绑定端口
server.bind(('127.0.0.1',8080)) # 端口范围 0-65535 0-1024操作系统使用
server.listen(5) # 设置最大挂起的连接数
while True: # 链接循环
conn, client_addr = server.accept()
while True: # 通信循环
cmd= conn.recv(1024) # 设置最大接受的字节数(bytes)
if not cmd: break # linux操作系统下,若客户端单方面断开连接会进入死循环
print('客户端数据', cmd)
# 执行客户端代码
obj = subprocess.Popen(cmd.decode(),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
stdout = obj.stdout.read()
stderr = obj.stderr.read()
conn.send(stdout+stderr)
'''
windows 下异常处理
while True:
try:
data = conn.recv(1024) # 设置最大接受的字节数(bytes)
print('客户端数据', data)
conn.send(data.upper())
except ConnectionResetError:
break
'''
conn.close()
server.close()
客户端
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1',8080))
# 客户端发收消息
while True:
msg = input('>>> ')
if not msg: continue
client.send(msg.encode()) # 字符串要转成而二进制
data = client.recv(1024)
client.close()