давайте рассмотрим этот код на python:
import socket
import threading
import sys
import select
class UDPServer:
def __init__(self):
self.s=None
self.t=None
def start(self,port=8888):
if not self.s:
self.s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.s.bind(("",port))
self.t=threading.Thread(target=self.run)
self.t.start()
def stop(self):
if self.s:
self.s.close()
self.t.join()
self.t=None
def run(self):
while True:
try:
#receive data
data,addr=self.s.recvfrom(1024)
self.onPacket(addr,data)
except:
break
self.s=None
def onPacket(self,addr,data):
print addr,data
us=UDPServer()
while True:
sys.stdout.write("UDP server> ")
cmd=sys.stdin.readline()
if cmd=="start\n":
print "starting server..."
us.start(8888)
print "done"
elif cmd=="stop\n":
print "stopping server..."
us.stop()
print "done"
elif cmd=="quit\n":
print "Quitting ..."
us.stop()
break;
print "bye bye"
Он запускает интерактивную оболочку, с помощью которой я могу запускать и останавливать сервер UDP.
Сервер реализован через класс, который запускает поток, в котором существует бесконечный цикл обратного вызова recv / onPacket внутри блока try / исключением, который должен обнаруживать ошибку и выходы из петля.
Я ожидаю, что когда я наберу «stop» на оболочке, сокет закроется, и функция recvfrom вызовет исключение из-за аннулирования дескриптора файла.
Вместо этого кажется, что recvfrom все еще блокирует поток, ожидающий данных, даже после вызова close .
Почему это странное поведение?
Я всегда использовал этот шаблон для реализации UDP-сервера в C ++ и JAVA, и он всегда работал.
Я также пытался с помощью " select " передать список с сокетом аргументу xread , чтобы получить событие нарушения дескриптора файла из выберите вместо этого из recvfrom , но select кажется "нечувствительным" к close тоже.
Мне нужен уникальный код, который будет поддерживать то же поведение в Linux и Windows с Python 2.5 - 2.6.
Спасибо.