zoukankan      html  css  js  c++  java
  • socket+循环通信+粘包

    Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。

    所谓粘包问题主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的。

    服务端

    from socket import *
    import subprocess
    import struct
    import json
    
    # 创建服务器
    server = socket(AF_INET, SOCK_STREAM)
    # 给服务器绑定地址
    server.bind(('127.0.0.1', 8080))
    # 创建半连接池
    server.listen(5)
    
    while True:
        # 建立连接
        conn, client_address = server.accept()
        print(client_address)
    
        while True:
            try:
                # 接受数据
                cmd = conn.recv(1024)
                if len(cmd) == 0:
                    break
                obj = subprocess.Popen(cmd.decode('utf-8'),
                                       shell=True,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE
                                       )
                stdout = obj.stdout.read()
                stderr = obj.stderr.read()
                # 创建报头
                header_dic = {
                    "filename": "a.txt",
                    "md5": "jgfjfgsga1972392lsdj",
                    "total_size": len(stdout) + len(stderr)
                }
                # 序列化报头
                header_json = json.dumps(header_dic)
                # 将报头转化成bytes格式
                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()
    
    server.close()
    View Code

    客户端

    from socket import *
    import struct
    import json
    
    # 创建客户端
    client = socket(AF_INET, SOCK_STREAM)
    # 向服务器发送连接请求
    client.connect(("127.0.0.1", 8080))
    
    while True:
        cmd = input(">>:").strip()
        if len(cmd) == 0:
            continue
        # 向服务器发送数据
        client.send(cmd.encode("utf-8"))
        
        # 获取报头长度
        header_size = struct.unpack("i", client.recv(4))[0]
        # 获取报头
        header_bytes = client.recv(header_size)
        header_json = header_bytes.decode("utf-8")
        header_dic = json.loads(header_json)
        print(header_dic)
        total_size = header_dic["total_size"]
        
        # 获取数据
        cmd_res = b""
        recv_size = 0
        while recv_size < total_size:
            data = client.recv(1024)
            recv_size += len(data)
            cmd_res += data
        print(cmd_res.decode('gbk'))
    
    client.close()
    View Code
  • 相关阅读:
    list切片
    class面向对象编程学习笔记
    斐波那契数
    module学习笔记
    Python基础
    产品经理培训行业---以起点学院为主体的相关竞品分析报告
    基础数据结构-二叉树-赫夫曼树的构建与编码
    大众点评APP分析随笔
    滴滴拼车功能分析
    梅沙教育APP简单分析-版本:iOS v1.2.21-Nathaneko-佳钦
  • 原文地址:https://www.cnblogs.com/liangchengyang/p/9578768.html
Copyright © 2011-2022 走看看