Python Client / Server Question

I am working on a python project. I have a client and server. The server listens for connections, and after receiving the connection, it waits for input from the client. The idea is that the client can connect to the server and execute system commands such as ls and cat. This is my server code:

import sys, os, socket host = '' port = 50105 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((host, port)) print("Server started on port: ", port) s.listen(5) print("Server listening\n") conn, addr = s.accept() print 'New connection from ', addr while (1): rc = conn.recv(5) pipe = os.popen(rc) rl = pipe.readlines() file = conn.makefile('w', 0) file.writelines(rl[:-1]) file.close() conn.close() 

And this is my client code:

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

When I start the server, I get the correct output saying that the server is listening. But when I connect to my client and type the command, the server exits with this error:

 Traceback (most recent call last): File "server.py", line 21, in <module> rc = conn.recv(2) File "/usr/lib/python2.6/socket.py", line 165, in _dummy raise error(EBADF, 'Bad file descriptor') socket.error: [Errno 9] Bad file descriptor 

On the client side, I get ls output, but the server is getting bolted.

+6
python command sockets client
source share
2 answers

Your code calls conn.close() and then goes back to conn.recv() , but conn already closed.

+6
source share

If you want your client to repeat what he does, just add a loop there :)

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

Most likely, you are closer to what you want.

Other comments:

 s.listen(1) 

This statement should probably be moved outside the while loop. You only need to call listen once.

 pipe = os.popen(rc) 

os.popen is deprecated, use the subprocess module instead.

 file = s.makefile('r', 0) 

You open a file, but never close a file. You should file.close() add file.close() after your call to sys.stdout.writelines() .

EDIT: reply below comment; made due to length and formatting

As it is, you read from the socket once, and then immediately close it. Thus, when the client sends the following command, it sees that the server has closed the socket and indicated an error.

The solution is to change the server code so that it can handle several commands. Please note that this is solved by introducing another cycle.

You need to wrap

 rc = conn.recv(2) pipe = os.popen(rc) rl = pipe.readlines() fl = conn.makefile('w', 0) fl.writelines(rl[:-1]) 

in another while True: so that it repeats until the client disconnects, and then wrap it in a try-except block that will catch an IOError that is called conn.recv () when the client disconnects.

try-except block should look like

 try: # the described above loop goes here except IOError: conn.close() # execution continues on... 
+3
source share

All Articles