Question

I have been trying to get a basic chat application working for months in python 2.7 (Using Geany IDE), and finally got a basic application working using UDP. I can connect and broadcast communications, but if a client connects and then closes later, the server crashes the next time it tries to broadcast a message to all of the clients. The issue is that it crashes without returning an error message or a traceback so I can't tell exactly what's happening. Here is the code (it will only work on windows due to the getch() code in the client).

Server:

from socket import *
s = socket(AF_INET,SOCK_DGRAM)
s.bind(("25.150.175.48",65437))
maxsize = 4096
listeners = []
while True:
    data, addr = s.recvfrom(maxsize)
    if addr not in listeners:
        listeners.append(addr)
        #print addr[1]
        print "new client added from %s on port %i" % (addr[0],addr[1])
    for l in listeners:
        try:
            s.sendto(data,l)
        except:
            listeners.remove(l)

Client:

from socket import *
import select
import msvcrt
s = socket(AF_INET,SOCK_DGRAM)
s.bind(("25.150.175.48",65438))#change port to 65439 for the second client
maxsize = 4096
waitseconds = 0.001
server = ("25.150.175.48",65437)
s.sendto(raw_input(">"),server)
while True:
    ready = select.select([s], [], [], waitseconds)
    if ready[0]:
        data = s.recv(maxsize)
        print data
    else:
        if msvcrt.kbhit():
            char = msvcrt.getch()
            if char == "\r":
                s.sendto(raw_input(">"),server)

My theory is that if I can have the server recognize when a person closes the client, I can remove the client address from the list of listeners and it will work fine. Unfortunately, it's not working correctly, and I don't know how to have the server send out a test packet of some sort that I can use to verify connection. All the examples I've read on the internet seem to just verify that the port exists. If anyone has any idea on how to handle this, I would greatly appreciate the help.

EDIT:

After tooling around a bit I finally managed to receive a traceback by running the server program in IDLE. the traceback is as follows:

Traceback (most recent call last):
  File "G:\Python\Miscellaneous\Examples\UDP Chat Server & Client\UDP server.py", line 7, in <module>
    data, addr = s.recvfrom(maxsize)
error: [Errno 10054] An existing connection was forcibly closed by the remote host

I need some help handling this, as my try/except statement seems to fail to catch this when I run it (Which I'm seriously concerned about; python bug?). After returning this traceback the program quits. Any suggestions?

Was it helpful?

Solution

You won't get any traceback with your try\except block. Unless you really know what you're doing you shouldn't ignore errors like that.

try:
    s.sendto(data,l)
except Exception as e:
    print(e)
    listeners.remove(l)

As for the crash it's hard to say. UDP is not connection oriented, so the client being running or not shouldn't crash your server, or even stop it from sending the packages.

The only way you can check if a client is online, using UDP exclusively, is by sending a package and removing it from the list if it doesn't respond in a period of time.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top