1

我一直试图让一个基本的聊天应用程序在 python 2.7(使用 Geany IDE)中工作几个月,最后得到一个使用 UDP 工作的基本应用程序。我可以连接和广播通信,但是如果客户端连接然后稍后关闭,服务器会在下次尝试向所有客户端广播消息时崩溃。问题是它在没有返回错误消息或回溯的情况下崩溃,所以我无法确切地知道发生了什么。这是代码(由于客户端中的代码,它只能在 Windows 上运行getch())。

服务器:

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)

客户:

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)

我的理论是,如果我可以让服务器识别一个人何时关闭客户端,我可以从侦听器列表中删除客户端地址,它会正常工作。不幸的是,它工作不正常,我不知道如何让服务器发送某种测试数据包,我可以用它来验证连接。我在互联网上阅读的所有示例似乎都只是验证端口是否存在。如果有人对如何处理此问题有任何想法,我将不胜感激。

编辑:

经过一番调试后,我终于设法通过在 IDLE 中运行服务器程序来接收回溯。回溯如下:

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

我需要一些帮助来处理这个问题,因为我的 try/except 语句在我运行它时似乎无法捕捉到它(我非常担心;python 错误?)。返回此回溯后,程序退出。有什么建议么?

4

1 回答 1

0

您的 try\except 块不会得到任何回溯。除非你真的知道你在做什么,否则你不应该忽略这样的错误。

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

至于坠机,很难说。UDP 不是面向连接的,因此正在运行的客户端不应该使您的服务器崩溃,甚至不应该阻止它发送包。

检查客户端是否在线(仅使用 UDP)的唯一方法是发送一个包,如果它在一段时间内没有响应,则将其从列表中删除。

于 2013-07-31T22:15:37.203 回答