zoukankan      html  css  js  c++  java
  • 解决tcp协议的粘包问题

    一、远程执行命令的程序

    服务端:

    from socket import *
    import subprocess

    server=socket(AF_INET,SOCK_STREAM)
    server.bind(('127.0.0.1',8080))
    server.listen(5)

    while True:
    conn,client_addr=server.accept() #(连接对象,客户端的ip和端口)
    print(client_addr)
    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()


    conn.send(stdout+stderr)

    except ConnectionResetError:
    break

    conn.close()
    server.close()


    客户端:
    from socket import *

    client=socket(AF_INET,SOCK_STREAM)
    client.connect(('127.0.0.1',8080))
    # print(client)

    while True:
    cmd=input('>>>: ').strip()
    if not cmd:continue
    client.send(cmd.encode('utf-8'))
    res=client.recv(1024)
    print(res.decode('gbk'))

    client.close()


    二、解决tcp协议的粘包问题

    补充struct模块:
        1、把整形数字转成bytes类型
        2、转成的bytes固定长度


    服务端:

    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_addr=server.accept()
    print('新的客户端',client_addr)

    while True:
    try:
    cmd=conn.recv(1024) #cmd=b'dir'
    if len(cmd) == 0:break

    # 运行系统命令
    obj=subprocess.Popen(cmd.decode('utf-8'),
    shell=True,
    stderr=subprocess.PIPE,
    stdout=subprocess.PIPE
    )

    stdout=obj.stdout.read()
    stderr=obj.stderr.read()

    #先制作报头
    header_dic={
    'filename':'a.txt',
    'total_size':len(stdout) + len(stderr),
    'hash':'xasf123213123'
    }
    header_json=json.dumps(header_dic)
    header_bytes=header_json.encode('utf-8')

    #1、先把报头的长度len(header_bytes)打包成4个bytes,然后发送
    conn.send(struct.pack('i',len(header_bytes)))
    #2、发送报头
    conn.send(header_bytes)
    #3、再发送真实的数据
    conn.send(stdout)
    conn.send(stderr)
    except ConnectionResetError:
    break

    conn.close()

    客户端:

    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'))

    #1、先收4个字节,该4个字节中包含报头的长度
    header_len=struct.unpack('i',client.recv(4))[0]

    #2、再接收报头
    header_bytes=client.recv(header_len)

    #从报头中解析出想要的内容
    header_json=header_bytes.decode('utf-8')
    header_dic=json.loads(header_json)
    print(header_dic)
    total_size=header_dic['total_size']


    #3、再收真实的数据
    recv_size=0
    res=b''
    while recv_size < total_size :
    data=client.recv(1024)
    res+=data
    recv_size+=len(data)

    print(res.decode('gbk'))
  • 相关阅读:
    重量传感器
    cotex_m3内核提供的ITM串口打印调试
    unsigned char 转字符串:
    手工双面打印
    Windows系统(服务器)忘记管理员登录密码:
    标准电流信号为什么是4-20MA?(网络摘录)
    LPC1768之ISP
    万用表的位数
    485收发控制器:
    [LeetCode] 534. Design TinyURL 设计短网址
  • 原文地址:https://www.cnblogs.com/kingyanan/p/9296143.html
Copyright © 2011-2022 走看看