我是一个python新手,深入研究为Python 1.5编写的旧代码。它基本上实现了一个UDP服务器,用于读取客户端发送的数据。代码如下所示:
import socket
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
serverSocket.bind('localhost', 778)
msg, sndr = serverSocket.recvfrom(2048)
这个套接字的问题在于,如果客户端发送失败,它可以无限期地等待消息接收(我试图修复的bug的来源)。我知道从Python 2.3开始,可以使用settimeout
方法,但不幸的是我必须坚持使用Python 1.5。如果有人可以帮助我使用代码片段/想法在这里拥有自己的超时功能,那就太棒了。
答案 0 :(得分:3)
任何语言中的任何socket tutorial都会解释在套接字上设置超时的select调用。没有理由看基于纸莎草的蟒蛇。
答案 1 :(得分:1)
如果您没有找到任何其他解决方案,您可以尝试使用我之前写的这个超时装饰器。检查它是否有效
import ctypes
import threading
import time
class timeout:
def __init__(self, timeout, kill_on_timeout=True):
self.__timeout = timeout
self.__kill_on_timeout = kill_on_timeout
def __call__(self, func):
def prep_func(*args, **kwargs):
result = args[0]
args = tuple(list(args)[1:])
try:
result.append(func(*args, **kwargs))
except Exception as e:
result.append(e)
def timeout_func(*args, **kwargs):
result = []
args = tuple([result]+list(args))
t = threading.Thread(target=prep_func, args=args, kwargs=kwargs)
t.daemon = True
t.start()
timeout_time = self.__timeout+time.time()
while True:
if time.time()>=timeout_time:
if self.__kill_on_timeout:
try:
terminate_thread(t)
except:
raise TimeoutReached('Could not kill the thread!')
raise TimeoutReached('Timeout reached! Thread killed.')
if result:
if not issubclass(type(result[0]), BaseException):
return result[0]
raise result[0]
time.sleep(0.001)
return timeout_func
def terminate_thread(thread):
if not thread.isAlive():
return None
exc = ctypes.py_object(SystemExit)
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(
ctypes.c_long(thread.ident), exc)
if res == 0:
raise ValueError('err')
elif res > 1:
ctypes.pythonapi.PyThreadState_SetAsyncExc(thread.ident, None)
raise SystemError('err')
class TimeoutReached(Exception):
pass
答案 2 :(得分:0)
好的,我通过使用select
模块找到了解决此问题的方法。
代码现在看起来如下:
import socket, select
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
serverSocket.bind('localhost',778)
while running: #running variable is set to True
incoming = select.select([serverSocket],[],[],5) #5 corresponds to timeout in seconds
try:
msg,sndr = incoming[0][0].recvfrom(2048)
except IndexError:
sys.stderr.write('Timed out in receiving message on UDP server')
continue