Python中如何正确实现UDP服务器Socket超时关闭?
解决UDP服务器30秒无数据自动关闭Socket的问题
要实现UDP服务器在30秒未收到客户端数据时自动关闭Socket,核心是利用Socket的超时机制,通过settimeout()方法设置阻塞调用的超时时间,捕获超时异常后执行关闭逻辑。
修改后的服务器代码
import ns_beam # my module import socket import pickle host = socket.gethostname() port_client = 60000 port_server = 50000 CLIENT_ADDRESS = (host, port_client) server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) server_socket.bind((host, port_server)) # 设置30秒超时,超过时间未收到数据则抛出socket.timeout异常 server_socket.settimeout(30) try: while True: try: message, address = server_socket.recvfrom(1024) recv_data = pickle.loads(message) # 反序列化数据 print(f"Received force from PS = {round(recv_data, 3)} [kN]") # 注意:原代码中element_number未定义,请确保已正确初始化该变量 result = ns_beam.num_sub_structure(f_sensor=recv_data, num_elem_tot=element_number) print(f"Displacement of NS = {round(result, 3)} [mm]") # 序列化并发送结果 sent_data = pickle.dumps(result) server_socket.sendto(sent_data, CLIENT_ADDRESS) except socket.timeout: print("30秒未收到客户端数据,准备关闭服务器Socket") break finally: # 确保无论是否发生异常,Socket都会被关闭 server_socket.close() print("服务器Socket已关闭")
关键修改说明
- 设置Socket超时:通过
server_socket.settimeout(30)给Socket设置30秒超时,当recvfrom()阻塞超过30秒未收到数据时,会抛出socket.timeout异常。 - 捕获超时异常:在循环内部捕获
socket.timeout异常,触发后跳出循环,进入后续关闭逻辑。 - finally块保证关闭:使用
try-finally结构,确保无论正常退出还是异常退出,Socket都会被正确关闭,避免资源泄漏。
客户端代码注意点
原客户端代码存在几处小问题,建议修正:
v_2_init变量未定义,需要提前初始化;- 外层
while True循环后的break语句位置错误,会导致循环直接终止,建议调整逻辑移除多余的break; - 发送数据的注释中有笔误("cent data"应为"send data")。
内容的提问来源于stack exchange,提问作者Yurii Yarema
相关产品推荐
相关产品推荐

