【问题标题】:Python UDP sendto() Ignoring Exception Block and CrashingPython UDP sendto() 忽略异常块和崩溃
【发布时间】:2013-07-31 21:40:35
【问题描述】:

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

服务器:

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 错误?)。返回此回溯后,程序退出。有什么建议吗?

【问题讨论】:

  • 回溯显示recvfrom()调用中的异常,而不是sendto()。也许在那里放一个 try 块并打印异常。然后您可以忽略/处理它。
  • 它按预期打印出异常,但我现在不知道如何处理该问题。代码有什么方法可以返回哪个客户端被强行关闭?或者至少是一个 IP?
  • 如果你在recvfrom()调用周围添加一个try块,你会在Exception对象中得到什么异常信息?
  • @pcm 如果我把它打印出来,我会得到这个:error: [Errno 10054] An existing connection was forcibly closed by the remote host。我可以通过某种方式获取故障客户端的 IP 吗?

标签: python exception-handling udp chat sendto


【解决方案1】:

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

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

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

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

【讨论】:

  • 我后来添加了异常以尝试修复崩溃,但它仍然继续发生。
  • 我更新了问题。通过在 IDLE 中运行我的初始代码,我设法得到了回溯错误。您的建议不起作用,因为代码似乎永远不会进入打印行。似乎 s.sendto() 正在手动关闭程序并绕过except。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-25
相关资源
最近更新 更多