0

I'm trying to create a basic server and client script. The idea is that the client can connect to the server and execute commands. Kinda like SSH but very simple. Heres my server code:

import sys, os, socket


host = ''                
port = 50103
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
print("Server started on port: ", port)
s.listen(1)
while (1):
    conn, addr = s.accept()
    print 'New connection from ', addr
    try:
        while True:
            rc = conn.recv(2)
            pipe = os.popen(rc)
            rl = pipe.readlines()
            fl = conn.makefile('w', 0)
            fl.writelines(rl[:-1])
            fl.close()
    except IOError:
            conn.close()

And here is my client:

import sys, socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = 'localhost'
port = input('Port: ')
s.connect((host, port))
while (1):
    cmd = raw_input('$ ')
    s.send(cmd) 
    file = s.makefile('r', 0)
    sys.stdout.writelines(file.readlines())
    file.close()

Here is my problem. I start the server and then run the client on the same machine. I enter the port and connect. Then I get the raw_input which is the '$'. If I type a command like 'ls' it just hangs on the client side. I have to exit the server for the client to receive the output of ls. By the way I am running Ubuntu Linux. Not sure if that matters.

2
  • Now I wrote your code for you anyway. The answer is updated. You can still do whatever you are trying to do with ssh, you know. Commented Jan 27, 2011 at 17:27
  • Please don't re-invent SSH. Some poor guy is going to have to support and maintain this! Commented Dec 12, 2011 at 0:52

2 Answers 2

2

When you makefile() on the socket and then use readlines() on it, it will continue until you reach an end of file, which in the socket case is that it closed from the other end.

Using makefile() in this case makes no sense to me, especially since you create it and close it after each command. Just use send() and recv() on both ends.

You probably also want to have some sort of actual "protocol" so the server tells the client "HERE COMES A RESPONSE" and "THIS IS THE END OF THE RESPONSE" so that the client knows. Otherwise it gets hard to know when to stop waiting for more response. :)

Update with an example that works:

server.py:

import sys, os, socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 50500))
print("Server started")
s.listen(1)
while True:
    print "Accepting"
    conn, addr = s.accept()
    print 'New connection from ', addr
    while True:
        try:
            rc = conn.recv(1024)
            print "Command", rc
            if not rc.strip():
                continue

            if rc.strip() == 'END':
                print "Close"
                conn.send("**END**")
                conn.close()
                break
            else:
                conn.send("This is the result of command %s\n" % rc)
        except Exception:
            conn.close()
            sys.exit()

client.py

import sys, os, socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 50500))
while True:
    cmd = raw_input('$ ')
    s.send(cmd) 
    result = s.recv(1024)
    print result
    if result == "**END**":
        print "Ending"
        break
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for this. Although it doesn't work as I don't get the output. I've been playing around with the code. I made it so it preforms output = os.system(rc) and then down below I did conn.send(output). So now it preforms the command on the server side but doesn't send to the client. Any ideas?
@AustinM: Well, how about sending it? And you still can do exactly what you are trying to do now, by typing "ssh <computername>", and you still haven't explained why aren't doing that.
I do try to send it I do conn.send(output) while output is set to os.system(rc). And it's for a simple project I need to finish up.
@AustinM: os.system(rc) will run the command rc. It will return if the command was successful or not. It will not return the output. Use subprocess instead. Read the docs, will you? And make sure that the variables contain what you think they contain. Programming is not a guessing game. You can't just go "I guess os.system(rc) returns the output", you have to CHECK. You evidently send things without having any clue of what you are sending. Why do you expect that to work? This is NOT magic incantations.
@AustinM: If you need to finish up the project: do this ssh <theothercomputer>. Log in, and now you have a prompt that does exactly what you are trying to do here and failing.
1

Well for one thing you're only connecting on the client once and on the server you're closing the socket after every read.

You should take a look at this example.

http://ilab.cs.byu.edu/python/socket/echoserver.html

You're doing quite a few things incorrectly.

1 Comment

Thanks. I've tried updating the code but whatever I try it just hangs on the client side :/ I've tried implementing some things in that example but it still wont work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.