I am playing with socket and tried to create simple chat server with only one client connection. Code and output as follows.
echo_server.py
import socket
host = ''
port = 4538
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(backlog)
print "Starting Server"
while 1:
client, address = s.accept()
try:
data = client.recv(size)
if data is not None:
if data is 'q':
print "I received request to close the connection"
client.send('q')
continue
print "I got this from client {}".format(data)
client.send(data)
continue
if data == 0:
client.close()
finally:
client.close()
echo_client.py
import socket
host = ''
port = 4538
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
try:
while 1:
message = filename = raw_input('Enter a your message: ')
s.send(message)
data = s.recv(1024)
if data is 'q':
print "You requested to close the connection"
break
print "Received from socket {}".format(data)
finally:
s.close()
Now, I had tried with sendall() too but it doesn't work. Following is the output on both sides
client:
Enter a your message: hello
Received from socket hello
Enter a your message: world
Received from socket
Enter a your message: hi
Traceback (most recent call last):
File "echo_client.py", line 12, in <module>
s.send(message)
socket.error: [Errno 32] Broken pipe
And on server
Starting Server
I got this from client hello
As you can see, the server doesn't get the second message(world). And replies with nothing and when I send third request to server with hi, client terminates with Broken Pipe How do I go about fixing it?
EDIT 1:
I changed the code now it's following. The s.accept() gets stuck in second request. Following is the code. echo_server.py
import socket
host = ''
port = 4538
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(backlog)
print "Starting Server"
try:
while 1:
print "BEFORE REQUEST"
client, address = s.accept()
print "AFTER REQUEST"
data = client.recv(size)
if data:
if data is 'q':
print "I received request to close the connection"
client.send('q')
print "I got this from client {}".format(data)
client.send(data)
else:
print "CLOSING IN ELSE"
client.close()
except:
print "CLOSING IN except"
client.close()
Following is the output.
BEFORE REQUEST
AFTER REQUEST
I got this from client hello
BEFORE REQUEST
As you can see for the second time accept() never returns. How to make it working?
recv
returns empty string when the client is closes the connection, not None
or 0
. Since empty string is a False condition, simply use if data:
or if not data:
.
And, as @JonClements pointed out, use an except
instead of a finally
in the server, or put the while
inside the try
and if not data: break
to exit the while
and execute the finally
.