1

I am creating a chat server in python and got quite far as a noob in the language. I am having 1 problem at the moment which I want to solve before I go further, but I cannot seem to find how to get the problem solved.

It is about a while loop that continues..

in the below code is where it goes wrong

while 1:
    try:
        data = self.channel.recv ( 1024 )
        print "Message from client: ", data
        if "exit" in data:
            self.channel.send("You have closed youre connection.\n")
            break
    except KeyboardInterrupt:
        break
    except:
        raise

When this piece of code get executed, on my client I need to enter "exit" to quit the connection. This works as a charm, but when I use CTRL+C to exit the connection, my server prints "Message from client: " a couple of thousand times.

where am I going wrong?

5
  • 3
    When you use CTRL+C, is that on the client or server side? Commented Nov 6, 2012 at 17:00
  • 1
    It sounds like you're closing the client. Recv probably returns false and thus you're stuck in the while loop. Commented Nov 6, 2012 at 17:02
  • I am using CTRL+C on the client side. Commented Nov 6, 2012 at 17:03
  • 2
    Think twice about using if 'exit' in data:. If this is a chat server, this means no one can ever send a message containing the word 'exit' unless they manage to make it span across 2 buffer-sized data blocks. if data == 'exit': will probably work more as you'd like. Commented Nov 6, 2012 at 17:12
  • @sr2222 I agree. However in the context of my chatserver, it does not seem to work if I replace the if statement with "if data == "exit" ", therefor I replaced the word with "/exit". This works fine now. Thx for the advice. Commented Nov 6, 2012 at 17:24

1 Answer 1

4

You're pressing Ctrl-C on the client side. This causes the server's self.channel to get closed.

Since calling recv() on a closed channel immediately returns a blank string, your server code gets stuck in an infinite loop.

To fix this, add the following line to your server code:

data = self.channel.recv ( 1024 )
if not data: break # <<< ADD THIS

Or, as suggested by @sr2222, you can combine both this and your current check into one:

if not data or 'exit' in data: 

This will exit the loop if the channel has been closed.

Sign up to request clarification or add additional context in comments.

4 Comments

Or just if not data or 'exit' in data:
Wow damm I indeed missed this... couldnt wrap my head around it, both the answer of NPE and sr2222 are correct. THX
Oh, sorry NPE, you are right, it's probably better to have 2 separate checks, since the 'exit' in data check sends data back over the connection, which will not be valid if data is empty.
@sr2222: Yes and no. AFAIK, calling send() on a closed channel is a no-op. However, some might question this approach on stylistic grounds.

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.