UDP Python sendto() Игнорирование блока исключений и сбоев
Я пытался заставить основное приложение чата работать в течение нескольких месяцев в 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/ Кроме, кажется, не может поймать это, когда я запускаю его (Что меня серьезно беспокоит; ошибка Python?). После возврата этой трассировки программа завершает работу. Какие-либо предложения?
1 ответ
Вы не получите никакой трассировки с вашим блоком try\ кроме. Если вы действительно не знаете, что делаете, вы не должны игнорировать подобные ошибки.
try:
s.sendto(data,l)
except Exception as e:
print(e)
listeners.remove(l)
По поводу крушения сказать сложно. UDP не ориентирован на установление соединения, поэтому клиент, работающий или не запущенный, не должен сбивать ваш сервер или даже мешать ему отправлять пакеты.
Единственный способ проверить, находится ли клиент в сети, используя исключительно UDP, - это отправить пакет и удалить его из списка, если он не отвечает в течение определенного периода времени.