1. 程式人生 > 其它 >python3 scoekt實現多執行緒互動式shell服務端

python3 scoekt實現多執行緒互動式shell服務端

技術標籤:pythonpythonsocket多執行緒

匯入模組

import socket importsubprocess

將要監聽的埠資訊設定好

host='0.0.0.0'
port=8081

首先實現一個命令執行函式,並將結果返回

def run_command(command):
    """執行命令"""
    command = command.rstrip()
    try:
        output = subprocess.check_output(
            command, stderr=subprocess.STDOUT, shell=True)
    except:
        output = b"Failed to execute command.\r\n"
    return output

接下來就是監聽設定好的埠,跟打印出狀態和連線的客戶端ip地址

def server_start():
    server=socket.socket()
    try:
        server.bind((host,port))
    except:
        print('Listening port failed!')
    print('[+] server start {}:{}'.format(host,str(port)))
    server.listen(5)
    conn,addr=server.accept()
    print('[+] client connect success {}:{}'.format(addr[0],str(addr[1])))

建立函式接受客戶端物件然後把接受的命令執行並返回,這裡建立這個函式是為了多執行緒去呼叫

def client_handler(client_obj):  
    while True:
        client_obj.send(b'<PyShell:#> ')
        cmd=client_obj.recv(2048).decode('utf-8')
        try:
            client_obj.send(run_command(cmd))
            print("Ready to exec command:%s" % cmd)
        except:
            pass

然後來把server_start函式部分完善,這裡記得把多執行緒模組匯入

def server_start():
    server=socket.socket()
    try:
        server.bind((host,port))
    except:
        print('Listening port failed!')
    print('[+] server start {}:{}'.format(host,str(port)))
    server.listen(5)
    while True:
        conn,addr=server.accept()
        print('[+] client connect success {}:{}'.format(addr[0],str(addr[1])))
        Go=threading.Thread(target=client_handler,args=(conn,))
        Go.start()

然後就是呼叫執行server_start函式

if __name__=='__main__':
    server_start()

現在執行效果已經差不多是我們想要的了

我們這裡在改改從命令列接受引數來指定ip跟埠監聽,匯入sys模組然後將host跟port宣告為全域性變數

import sys

global host
global port

然後在呼叫server_start函式前加上獲取的程式碼

if __name__=='__main__':
    host=sys.argv[1]
    port=int(sys.argv[2])
    server_start()

這裡我們加上異常處理,如果沒有傳入值或者錯誤設定為預設ip跟埠

if __name__=='__main__':
    try:
        host=sys.argv[1]
        port=int(sys.argv[2])
    except:
        host='0.0.0.0'
        port=5201
    server_start()

到這裡功能就都實現了,貼一下完整程式碼跟效果圖

import socket
import subprocess
import threading
import sys

global host
global port

def run_command(command):
    """執行命令"""
    command = command.rstrip()
    try:
        output = subprocess.check_output(
            command, stderr=subprocess.STDOUT, shell=True)
    except:
        output = b"Failed to execute command.\r\n"
    return output

def client_handler(client_obj):  
    while True:
        client_obj.send(b'<PyShell:#> ')
        cmd=client_obj.recv(2048).decode('utf-8')
        try:
            client_obj.send(run_command(cmd))
            print("Ready to exec command:%s" % cmd)
        except:
            pass

def server_start():
    server=socket.socket()
    try:
        server.bind((host,port))
    except:
        print('Listening port failed!')
    print('[+] server start {}:{}'.format(host,str(port)))
    server.listen(5)
    while True:
        conn,addr=server.accept()
        print('[+] client connect success {}:{}'.format(addr[0],str(addr[1])))
        Go=threading.Thread(target=client_handler,args=(conn,))
        Go.start()

if __name__=='__main__':
    try:
        host=sys.argv[1]
        port=int(sys.argv[2])
    except:
        host='0.0.0.0'
        port=5201
    server_start()