我一直在寻找,在这里:如何在python's套接字接收方法上设置超时?
和其他人,但我似乎不能让它像我想要的那样工作。我正在编写一个traceroute脚本,并希望程序抛出超时异常,如果它已经等待超过10秒的答复,从它刚刚发送的数据包,所以它可以移动到下一跳。我有几个额外的except来尝试捕获超时,但它永远不会捕获(甚至抛出)异常。
try:
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
#setup receive socket
recv_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
recv_socket.bind(("", 8888))
#recv_socket.settimeout(10)
recv_socket.setblocking(0)
ready = select.select([recv_socket], [], [], 10)
except socket.error , msg:
print 'Socket could not be created. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
# tell kernel not to put in headers, when using IPPROTO_RAW this is not necessary
# s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
# Get usable hostname
destination_address = socket.gethostbyname('www.google.com')
max_ttl = 50
ttl = 1
while(1):
# Timer
t_start = time.time()
s.sendto(constructPacket(ttl,'129.196.196.163',destination_address), (destination_address , 0 ))
# Receive and output
# need to add, if no receive, timeout and increase ttl by one
curr_addr = None
curr_name = None
try:
if ready[0]:
_, curr_addr = recv_socket.recvfrom(512)
curr_addr = curr_addr[0]
else:
print 'Timeout'
try:
curr_name = socket.gethostbyaddr(curr_addr)[0]
except socket.error:
curr_name = curr_addr
except timeout, e:
print 'Timeout'
except socket.error, e:
print 'Socket Error. Error Code : ' + str(e[0]) + ' Message ' + e[1]
sys.exit()
if curr_addr is not None:
curr_host = "%s (%s)" % (curr_name, curr_addr)
else:
curr_host = "*"
print "%d | %s | %dms" % (ttl, curr_host,(time.time()-t_start)*1000)
ttl = ttl + 1
if curr_addr == destination_address or ttl == max_ttl:
s.close()
recv_socket.close()
break
非阻塞模式下不存在超时异常。对select()
使用timeout参数,并检测select()
返回时没有任何就绪套接字的情况。