Reputation: 10269
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?
Upvotes: 0
Views: 1877
Reputation: 177901
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
.
Upvotes: 2