• 解决粘包问题-终极版


    server------------------

    #!/usr/bin/env python
    # encoding: utf-8  
    # Date: 2018/6/5


    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)
    phone.bind(('127.0.0.1', 8081))
    phone.listen(5)

    print('starting.......')
    while True:  # 链接循环,保证客户端停止,服务端不停止,但是不支持并发
        conn, client_addr = phone.accept()
        print(client_addr)

        while True:
            try:  # window异常捕获
                # 1 接收命令
                cmd = conn.recv(1024)
                if not cmd:  # 适用于linux
                    break  # 客户端断掉,发送空过来
                print('客户端的数据', cmd)
                # 2 执行命令,拿到结果
                obj = subprocess.Popen(cmd.decode('utf-8'), shell=True,
                                       stdout = subprocess.PIPE,
                                        stderr = subprocess.PIPE)
                stdout = obj.stdout.read()
                stderr = obj.stderr.read()
                # 3把命令的结果返回客户端
                # 第一步:制作固定长度的报头
                header_dic = {
                    'filename': 'a.txt',
                    'md5': 'xxdxx',
                    'total_size': len(stdout) + len(stderr)
                }
                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 ConnectionResetError:
                break
        conn.close()
    phone.close()



    client--------------------

    #!/usr/bin/env python
    # encoding: utf-8  
    # Date: 2018/6/5


    import socket
    import struct
    import json

    phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    phone.connect(('127.0.0.1', 8081))

    while True:
        # 1发命令
        cmd = input('>>>:').strip()
        if not cmd:continue
        phone.send(cmd.encode('utf-8')) # 应用程序发给操作系统,操作系统调用网卡
        # 那命令结果
        #  第一步:先收报头长度
        obj = phone.recv(4)
        header_size = struct.unpack('i', obj)[0]

        # 第二步:收报头
        header_bytes = phone.recv(header_size)
        # 第三步:从报头中解析出对真实数据的描述信息
        header_json = header_bytes.decode('utf-8')
        header_dic = json.loads(header_json)
        total_size = header_dic['total_size']
        # 第三步:接收真实的数据
        recv_size = 0
        recv_data = b''
        while recv_size < total_size:
            res = phone.recv(1024)
            recv_data += res
            recv_size += len(res)
        print(res.decode('utf-8'))

    phone.close()




  • 相关阅读:
    【Demo】QQ,github,微博第三方社交登录
    crontab执行时间和系统时间不一致
    CDN服务技术架构图
    【php】命名空间 和 自动加载的关系
    【运维工具】Git代码发布系统
    【ipv6惹的祸】curl 超时
    MySQL:动态开启慢查询日志(Slow Query Log)
    Virtualbox 虚拟机支持硬件摄像头
    网页取消快照、禁止抓取等meta标签功能
    ajax 跨域
  • 原文地址:https://www.cnblogs.com/fmgao-technology/p/9189453.html
Copyright © 2020-2023  润新知