美文网首页
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