简体   繁体   中英

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 .

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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