美文网首页
tcp远端命令执行--解决粘包

tcp远端命令执行--解决粘包

作者: 温柔倾怀 | 来源:发表于2019-07-15 12:01 被阅读0次

    客户端服务端通信简图

    两种粘包现象

    解决粘包现象

    只有tcp通信存在粘包现象
    udp会直接产生OSError异常

    客户端

    from socket import *
    import struct
    from functools import partial
    
    ip_port = ('127.0.0.1',8080)
    back_log =5
    buffer_size = 1024
    
    tcp_client = socket(AF_INET,SOCK_STREAM)
    tcp_client.connect(ip_port)
    
    while True:
        cmd = input(">>:").strip()
        if not cmd:continue
        if cmd == 'quit':break
        tcp_client.send(cmd.encode('utf8'))
    
        #解决粘包
        length_data = tcp_client.recv(4) #接受数据长度
        length = struct.unpack('i',length_data)[0]
        #开始接受数据
        # recv_size = 0
        # recv_msg = b''
        # while recv_size<length:
        #     recv_msg += tcp_client.recv(buffer_size)
        #     recv_size = len(recv_msg)
        #牛逼的代码--这里实现有些问题--学习这种牛逼的写法
        recv_msg = ''.join(iter(partial(tcp_client.recv,buffer_size),b''))
    
        print(recv_msg.decode('gbk'))
    tcp_client.close()
    
    

    服务端

    
    from socket import *
    import subprocess
    import struct
    
    ip_port = ('127.0.0.1',8080)
    back_log =5
    buffer_size = 1024
    
    tcp_server = socket(AF_INET,SOCK_STREAM)
    tcp_server.bind(ip_port)
    tcp_server.listen(back_log)
    
    while True:
        conn,addr = tcp_server.accept()
        print("新的客户端",addr)
        while True:
            # 接收到的是客户端发来的命令,服务端执行,并返回结果
            try:
                cmd = conn.recv(buffer_size).decode('utf8')
                if not cmd:break
                print("客户端命令:",cmd)
                #执行命令
                res = subprocess.Popen(cmd,shell=True,
                                       stdout=subprocess.PIPE,
                                       stdin=subprocess.PIPE,
                                       stderr=subprocess.PIPE)
                err = res.stderr.read()
                if err:
                    cmd_res = err
                else:
                    cmd_res = res.stdout.read()
                # 命令正常执行没有返回值得情况下,比如cd ..
                if not cmd_res:
                    cmd_res = 'exec success'.encode('gbk')
                #解决粘包
                length = len(cmd_res)
                data_length = struct.pack('i',length)
                #下面两个send会黏到一起;在客户端解决:第一次接受数据长度;第二次开始接受数据
                #定制报文头
                conn.send(data_length)
                #真实发送数据
                conn.send(cmd_res)
            except ConnectionResetError as e:
                print(e)
                break
        conn.close()
    tcp_server.close()
    
    

    相关文章

      网友评论

          本文标题:tcp远端命令执行--解决粘包

          本文链接:https://www.haomeiwen.com/subject/lxlgkctx.html