基于tgp协议的套接字的 粘包解决

客户端

import socket
import struct
import json
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #买手机
phone.connect(('127.0.0.1', 8082)) #绑定手机卡

#发,收消息
while True:
    cmd = input('>>: ').strip()
    if not cmd:continue

    phone.send(cmd.encode('utf-8'))
    #先收报头的长度
    header_len = struct.unpack('i', phone.recv(4))[0]

    #再收报头
    header_bytes = phone.recv(header_len)
    header_json = header_bytes.decode('utf-8')
    header_dic = json.loads(header_json)
    total_size = header_dic['total_size']

    #最后收数据
    recv_size = 0 #10241=10240+1
    total_data = b''
    while recv_size < total_size:
        recv_data = phone.recv(1024)
        recv_size += len(recv_data)
        total_data += recv_data
    print(total_data.decode('gbk'))
phone.close()

服务端

import socket
import subprocess
import struct
import json
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加
phone.bind(('127.0.0.1',8082)) #绑定手机卡
phone.listen(5) #开机

print('starting...')
while True: #链接循环
    conn,client_addr=phone.accept() #等电话 (链接,客户的的ip和端口组成的元组)
    print('-------->',conn,client_addr)

    #收,发消息
    while True:#通信循环
        try:
            cmd = conn.recv(1024)
            if not cmd:break #针对linux
            #执行cmd命令,拿到cmd的结果,结果应该是bytes类型
            #。。。。
            res = subprocess.Popen(cmd.decode('utf-8'), shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
            stdout = res.stdout.read()
            stderr = res.stderr.read()
            #制作报头
            header_dic = {
                'total_size': len(stdout)+len(stderr),
                'filename': None,
                'md5': None}

            header_json = json.dumps(header_dic)
            header_bytes = header_json.encode('utf-8')
            #发送阶段
            #先发报头长度
            conn.send(struct.pack('i', len(header_bytes)))
            #再发报头
            conn.send(header_bytes)

            #最后发送命令的结果
            conn.send(stdout)
            conn.send(stderr)
        except Exception:
            break
    conn.close() #挂电话
phone.close() #关机

 

posted @ 2017-08-28 18:26  Python界-黄药师  阅读(213)  评论(0编辑  收藏  举报