Ishan Bhatt
Ishan Bhatt

Reputation: 10269

How to fix broken pipe in Chat server using socket in Python after first request?

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

Answers (1)

Mark Tolonen
Mark Tolonen

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

Related Questions