zoukankan      html  css  js  c++  java
  • PYTHON——TCP&UDP:Socket实现远程执行命令

      本文介绍客户端client输入dos指令,并将dos指令发送给服务端server,服务端接收到指令,通过调用subprocess模块的Popen方法实例化一个子进程对象,子进程对象执行完指令后,将结果并通过管道方式回送到主进程。其中,subprocess的用法,参见:Python subprocess模块解析

    一、通过发送字符串长度的方法:

    1、服务端程序:cmd_server.py:

    import socket
    import subprocess
    import time
    # subprocess.Popen() 重要方法. # 学socket的秘籍:一收一发 sk = socket.socket() host='' #空表示本机,等效于127.0.0.1和localhost port=8000 address = (host,port) sk.bind(address) sk.listen(3) print('waiting......') # conn,addr = sk.accept() #这个conn是客户端的socket对象。非常重要。 while True: conn, addr = sk.accept() # 这个conn是客户端的socket对象。非常重要。 print(addr) while True: try: data = conn.recv(1024) except Exception: break if not data: #客户端退出时,最后还是会给服务端发送一个空串。即data为空。 break print('--------->',str(data,'utf8')) obj=subprocess.Popen(str(data,'utf8'),shell=True,stdout=subprocess.PIPE) cmd_result = obj.stdout.read() #bytes类型 result_len = bytes(str(len(cmd_result)),'utf8') conn.sendall(result_len) #必须先传一个长度过去
    # time.sleep(1) #两个发送指令send或sendall连在一起,会出现粘包现象。解决粘包现象,就是加入sleep
         conn.recv(1024) #通过一收一发方式,多引入一个短收,解决粘包问题。
    conn.sendall(cmd_result)
    conn.close()

    2、客户端程序:cmd_client.py:

    import socket
    
    sk=socket.socket()
    address = ('127.0.0.1',8000)
    sk.connect(address)
    
    while True:
        inp = input('>>>')
        if inp=='exit':
            break
        sk.send(bytes(inp,'utf8'))
        result_len = int(str(sk.recv(1024),'utf8'))
    sk.send(bytes('ok')) #用于解决粘包现象
    print(result_len) data=bytes() #初始化一个bytes类型的变量,就像初始化sum=0一样 while len(data)!=result_len: temp = sk.recv(1024) data += temp print(str(data,'gbk')) sk.close()

    二、更好的方法:

    1、服务端程序:cmd_server.py:

    import socket
    import subprocess
    
    # subprocess.Popen() 重要方法.
    # 学socket的秘籍:一收一发
    sk = socket.socket()
    host=''  #空表示本机,等效于127.0.0.1和localhost
    port=8000
    address = (host,port)
    sk.bind(address)
    sk.listen(3)
    print('waiting......')
    # conn,addr = sk.accept()  #这个conn是客户端的socket对象。非常重要。
    
    while True:
        conn, addr = sk.accept()  # 这个conn是客户端的socket对象。非常重要。
        print(addr)
        while True:
            try:
                data = conn.recv(1024)
            except Exception:
                break
            if not data:  #客户端退出时,最后还是会给服务端发送一个空串。即data为空。
                break
            print('--------->',str(data,'utf8'))
            obj=subprocess.Popen(str(data,'utf8'),shell=True,stdout=subprocess.PIPE)
            cmd_result = obj.stdout.read()  #bytes类型
    # result_len = bytes(str(len(cmd_result)),'utf8')
    # conn.sendall(result_len) #必须先传一个长度过去
    # conn.recv(1024) #两个发送指令send或sendall连在一起,可能会出现粘包现象。解决粘包现象,就是加入临时阻塞
    conn.sendall(cmd_result)
    conn.close()

    2、客户端程序:cmd_client.py

    import socket
    
    sk=socket.socket()
    address = ('127.0.0.1',8000)
    sk.connect(address)
    buffersize=1024
    while True:
        inp = input('>>>')
        if inp=='exit':
            break
        sk.send(bytes(inp,'utf8'))
        fullDataBtyes = b''  #初始化一个bytes类型的变量,等效于fullDataBytes=bytes()。
        while True:
            data = sk.recv(buffersize)
            fullDataBtyes += data
            if len(data)<buffersize:
                break;
        print(str(fullDataBtyes,'gbk'))
    
        # result_len = int(str(sk.recv(1024),'utf8'))
        # sk.send(bytes('ok')) #解决粘包
        # print(result_len)
        # data=bytes()  #初始化一个bytes类型的变量,就像初始化sum=0一样
        # while len(data)!=result_len:
        #     temp = sk.recv(1024)
        #     data += temp
        # print(str(data,'gbk'))
    
    sk.close()

    参考:

    1、‘’老男孩‘’python全栈开发,袁老师讲解

    2、参考《python从菜鸟到高手》,作者:李宁

  • 相关阅读:
    Get distinct count of rows in the DataSet
    单引号双引号的html转义符
    PETS Public English Test System
    Code 39 basics (39条形码原理)
    Index was outside the bounds of the array ,LocalReport.Render
    Thread was being aborted Errors
    Reportviewer Error: ASP.NET session has expired
    ReportDataSource 值不在预期的范围内
    .NET/FCL 2.0在Serialization方面的增强
    Perl像C一样强大,像awk、sed等脚本描述语言一样方便。
  • 原文地址:https://www.cnblogs.com/chenhaiming/p/9886288.html
Copyright © 2011-2022 走看看