套接字-解决粘包与并发

# tcp服务端
import socketserver
import subprocess
import json
import struct


class MyRequestHandle(socketserver.BaseRequestHandler):
    def handle(self):  # 创建通信循环
        while 1:
            try:
                recv_data = self.request.recv(1024)  # 尝试接客户端指令
                if len(recv_data) == 0:
                    break
                obj = subprocess.Popen(recv_data.decode('utf-8'),
                                       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)  # 计算实际发送数据长度
                head_dict = {'total_size': total_size}  # 编成报头信息字典
                json_str = json.dumps(head_dict)  # 把报头信息转为json格式的字符串
                json_str_bytes = json_str.encode('utf-8')  # 再把报头信息转为bytes
                tag = struct.pack('i', len(json_str_bytes))  # 最后把报头信息转为固定的4位的标识
                self.request.send(tag)  # 先发4位标识
                self.request.send(json_str_bytes)  # 再发报头信息
                self.request.send(stdout_res)  # 最后发实际数据
                self.request.send(stderr_res)
            except Exception as e:
                print(e)
                break
        self.request.close()


s = socketserver.ThreadingTCPServer(('127.0.0.1', 3000), MyRequestHandle)
s.serve_forever()  # 循环从半连接池拿出请求
# tcp客户端
import socket
import struct
import json

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 3000))
while 1:
    send_data = input('输入发给服务端的指令:').strip()  # 在客户端由用户输入指令
    if len(send_data) == 0:
        continue
    client.send(send_data.encode('utf-8'))  # 发送指令给服务端
    tag = client.recv(4)  # 首先接收报头4位标识
    head_dict_len = struct.unpack('i', tag)[0]
    json_str_bytes = client.recv(head_dict_len)  # 根据4位标识解出的长度接收报头字典
    json_str = json_str_bytes.decode('utf-8')
    head_dict = json.loads(json_str)  # 根据报头字典里面的
    total_size = head_dict.get('total_size')  # 根据报头字典里面的数据长度接收实际数据
    recv_size = 0
    while recv_size < total_size:  # 循环接收实际数据并打印
        recv_data = client.recv(1024)
        recv_size += len(recv_data)
        print(recv_data.decode('gbk'), end='')
    print()

猜你喜欢

转载自www.cnblogs.com/caoyu080202201/p/12749501.html