Python 通过套接字发送命令

发布于 2024-10-17 17:59:35 字数 1297 浏览 3 评论 0原文

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


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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

痴意少年 2024-10-24 17:59:35

危险,威尔·罗宾逊!!!

您确实想在不通过网络进行身份验证的情况下以明文形式发送命令吗?这是非常非常危险的。

使用 paramiko 通过 SSH 完成此操作。

好吧,这个答案我听过太多次了。我不想使用 SSH,我只是构建它来了解有关套接字的更多信息。如果我想向系统发送命令,我不会实际使用它。 – 奥斯汀M

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

套接字模块是 posix 库上的一个薄层;普通的插座既乏味又难以正确使用。截至今天(2014 年),异步 I/O 和并发性并不是 Python 最强的特性 - 3.4 开始改变这一点,但库将落后一段时间。我的建议是花时间学习一些更高级别的 API,例如 Twisted (twistedmatrix.com/trac)。如果您确实对底层内容感兴趣,请深入研究项目源代码。

好吧。关于如何使用扭曲来处理这种类型的事情有什么想法吗? – 奥斯汀M

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

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.

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. 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; 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. My advice is to spent your time learning some higher level API like 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

骷髅 2024-10-24 17:59:35

好吧,我可以理解你的沮丧奥斯汀;我也在同一条船上。然而,反复试验最终成功了。希望您正在寻找这个:

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)

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)
扮仙女 2024-10-24 17:59:35

目前还不清楚为什么在客户端和服务器中使用 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

It's unclear why you are using subprocess.Popen() for the same command in both the client and the server. 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
奈何桥上唱咆哮 2024-10-24 17:59:35

您的代码的问题在于这一行(在客户端和服务器中):

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

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

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

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. 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.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文