简体   繁体   English

Python通过套接字发送命令

[英]Python sending command over a socket

I'm having a bit of trouble. 我有点麻烦。 I want to create a simple program that connects to the server and executes a command using subprocess then returns the result to the client. 我想创建一个连接到服务器并使用子进程执行命令的简单程序,然后将结果返回给客户端。 It's simple but I can't get it to work. 它很简单,但我不能让它工作。 Right now this is what I have: client: 现在这就是我所拥有的:客户:


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")

server: 服务器:


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()

Danger, Will Robinson!!! 威尔罗宾逊危险!

Do you really want to send commands in clear text without authentication over the network? 您是否真的希望以明文形式发送命令而无需通过网络进行身份验证? It is very, very dangerous. 这非常非常危险。

Do it over SSH with paramiko . 通过SSH与paramiko一起

Alright I've heard this answer too many times. 好吧,我多次听到这个答案。 I don't want to use SSH I'm just building it to learn more about sockets. 我不想使用SSH我只是构建它以了解有关套接字的更多信息。 I'm not going to actually use this if I want to send commands to a system. 如果我想将命令发送到系统,我不打算实际使用它。 – AustinM - 奥斯汀

There is no way I could infer this noble quest from your question. 我无法从你的问题中推断出这种崇高的追求。 :-) :-)

The sockets module is a thin layer over the posix library; 套接字模块是posix库上的一个薄层; plain sockets is tedious and hard to get right. 普通插座很乏味,很难做到。 As of today (2014), asynchronous I/O and concurrency are not among Python's strongest traits - 3.4 is starting to change that but libraries will lag behind for a while. 截至今天(2014年),异步I / O和并发性并不是Python最强大的特征之一 - 3.4开始改变它,但是库会滞后一段时间。 My advice is to spent your time learning some higher level API like Twisted ( twistedmatrix.com/trac ). 我的建议是花时间学习一些更高级的API,如Twisted( twistedmatrix.com/trac )。 If you are really interested in the low level stuff, dive in the project source. 如果您真的对低级别的东西感兴趣,请参考项目源代码。

Alright. 好的。 Any idea on how I could use twisted for this type of thing? 关于如何使用扭曲这种类型的东西的任何想法? – AustinM - 奥斯汀

Look at twistedmatrix.com/documents/current/core/examples/#auto2 请看twistedmatrix.com/documents/current/core/examples/#auto2

Well I can understand your frustration Austin; 好吧,我能理解你的沮丧奥斯汀; I was in the same boat. 我在同一条船上。 However trial and error at last worked out. 然而,试验和错误终于解决了。 Hopefully you were looking for this: 希望你在寻找这个:

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)

It's unclear why you are using subprocess.Popen() for the same command in both the client and the server. 目前还不清楚为什么在客户端和服务器中对同一命令使用subprocess.Popen() Here's an outline of what I would try to do (pseudocode): 这是我要尝试做的概述(伪代码):

client 客户

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

server 服务器

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

The problem with your code is this line (in both client and server): 您的代码的问题是这一行(在客户端和服务器中):

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

You are calling wait on the Popen object, which means that the variable proc is getting an int (returned by wait ) instead of a Popen object. 您正在调用Popen对象上的wait ,这意味着变量proc获取一个int(由wait返回)而不是Popen对象。 You can just get rid of the wait -- since communicate waits for the process to end before returning, and you aren't checking the exit code anyway, you don't need to call it. 你可以摆脱wait - 因为communicate在返回之前等待进程结束,而你还没有检查退出代码,你不需要调用它。

Then, in your client, I don't think you even need the subprocess calls, unless you're running some command that the server is sending back. 然后,在您的客户端中,我认为您甚至不需要子进程调用,除非您正在运行服务器正在发回的某个命令。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM