黏包问题解决方案

服务端

复制代码
from socket import *
import subprocess
import struct,json
server = socket(AF_INET,SOCK_STREAM)
server.setsockopt(SOL_SOCKET,SO_EXCLUSIVEADDRUSE,1)
server.bind(('127.0.0.1',8888))
server.listen(5)
while True:
    conn,addr = server.accept()
    print('收到来自%s的访问' % addr[0])
    while True:
        try:
            cmd = conn.recv(1024)
            cmd = cmd.decode("utf-8")
            ret = subprocess.Popen(cmd,shell=True,
                                   stdout=subprocess.PIPE,   #正确输出
                                   stderr=subprocess.PIPE,   #错误输出
                                   )
            stdout = ret.stdout.read()
            stderr = ret.stderr.read()
            #发送之前先创建一个报头
            total_size = len(stdout) + len(stderr)
            #报头必须是定长,不然发过去,不知道边界也没有意义
            # 先创建一个报头
            header_dict = {'total_size':total_size,
                           "md5":78978900967890878,
                           "filename":"a.txt"
                           }
            header_str = json.dumps(header_dict)
            header_bytes = header_str.encode('utf-8')
            header_size = struct.pack('i',len(header_bytes))
            conn.send(header_size)
            conn.send(header_bytes)
            conn.send(stdout)
            conn.send(stderr)
        except ConnectionResetError:
            break
    conn.close()
server.close()
复制代码

客户端

复制代码
from socket import *
import struct,json
client = socket()
client.connect(('127.0.0.1',8888))
while True:
    cmd = input(">>>").strip()
    if len(cmd) == 0:continue
    client.send(cmd.encode("utf-8"))

    header = client.recv(4)  #接收报头
    header_size = struct.unpack('i',header)[0] #得到报头长度
    # print(header_size)

    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"]
    fact_size = 0
    fact = b''
    while fact_size < total_size:
        data = client.recv(1024)
        fact += data
        fact_size += len(data)
    print(fact.decode('gbk'))
client.close()
复制代码

 

posted @   明王不动心  阅读(168)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示