• 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从菜鸟到高手》,作者:李宁

  • 相关阅读:
    webpack
    localStorage使用总结
    html5 的localstorage
    js 的登录验证
    webpack vue2.0项目脚手架生成的webpack文件
    vue2.0 keep-alive最佳实践
    npm 的指令介绍
    vue2.0 子组件和父组件之间的传值
    electron的通信
    electron 的窗口设置最大化 最小化
  • 原文地址:https://www.cnblogs.com/chenhaiming/p/9886288.html
Copyright © 2020-2023  润新知