Python通过套接字发送命令

时间:2011-02-13 21:40:44

标签: python client subprocess execution

我遇到了一些麻烦。我想创建一个连接到服务器并使用子进程执行命令的简单程序,然后将结果返回给客户端。它很简单,但我不能让它工作。现在这就是我所拥有的: 客户端:


import sys, socket, subprocess
conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = sys.argv[1]
port = int(sys.argv[2])
socksize = 1024
conn.connect((host, port))
while True:
    shell = raw_input("$ ")
    conn.send(shell)
    data = conn.recv(socksize)
    #msglen = len(data)
    output = data
    iotype = subprocess.PIPE
    cmd = ['/bin/sh', '-c', shell]
    proc = subprocess.Popen(cmd, stdout=iotype).wait()
    stdout,stderr = proc.communicate()
    conn.send(stdout)
    print(output)
    if proc.returncode != 0:
        print("Error")

服务器:


import sys, socket, subprocess
host = ''               
port = 50106
socksize = 1024

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
print("Server started on port: %s" %port)
s.listen(1)
print("Now listening...\n")
conn, addr = s.accept()
while True:
    print 'New connection from %s:%d' % (addr[0], addr[1])
    data = conn.recv(socksize)
    cmd = ['/bin/sh', '-c', data]
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE).wait()
    stdout,stderr = cmd.communicate()
    if not data:
        break
    elif data == 'killsrv':
        sys.exit()

4 个答案:

答案 0 :(得分:7)

危险,威尔罗宾逊!

您是否真的希望以明文形式发送命令而无需通过网络进行身份验证?这是非常非常危险的。

使用paramiko通过SSH进行。

  

好吧,我听过这个答案太多次了。我不想使用SSH我只是构建它以了解有关套接字的更多信息。如果我想将命令发送到系统,我不打算实际使用它。 - AustinM

我无法从你的问题中推断出这一崇高的追求。 : - )

套接字模块是posix库上的一个薄层;普通插座很乏味,很难做到。截至今天(2014年),异步I / O和并发性并不是Python最强大的特征之一 - 3.4开始改变它,但是库会滞后一段时间。我的建议是花时间学习一些更高级的API,如Twisted(twistedmatrix.com/trac)。如果你真的对低级别的东西感兴趣,可以深入了解项目资源。

  

好的。关于如何使用扭曲这种类型的东西的任何想法? - AustinM

查看twistedmatrix.com/documents/current/core/examples/#auto2

答案 1 :(得分:3)

我能理解你的沮丧奥斯汀;我在同一条船上。然而,试验和错误终于解决了。希望你在寻找这个:

print "Command is:",command
op = subprocess.Popen(command, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
if op:
    output=str(op.stdout.read())
    print "Output:",output
    conn.sendall(output)

else:
    error=str(op.stderr.read())
    print "Error:",error
    conn.sendall(error)

答案 2 :(得分:1)

目前还不清楚为什么在客户端和服务器中使用subprocess.Popen()来执行相同的命令。这是我将尝试做的概述(伪代码):

客户端

while True:
    read command from user
    send command to server
    wait for and then read response from server
    print response to user

服务器

while True:
    wait for and then read command from client
    if command is "killsrv", exit
    execute command and capture output
    send output to client

答案 3 :(得分:0)

您的代码存在问题(在客户端和服务器中):

proc = subprocess.Popen(cmd, stdout=iotype).wait()
stdout,stderr = proc.communicate()

您正在wait对象上调用Popen,这意味着变量proc正在获取一个int(由wait返回)而不是Popen对象。您可以摆脱wait - 因为communicate在返回之前等待进程结束,并且您还没有检查退出代码,您不需要调用它。 / p>

然后,在您的客户端中,我认为您甚至不需要子进程调用,除非您正在运行服务器发回的某个命令。