You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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已关闭")

关键修改说明

  1. 设置Socket超时:通过server_socket.settimeout(30)给Socket设置30秒超时,当recvfrom()阻塞超过30秒未收到数据时,会抛出socket.timeout异常。
  2. 捕获超时异常:在循环内部捕获socket.timeout异常,触发后跳出循环,进入后续关闭逻辑。
  3. finally块保证关闭:使用try-finally结构,确保无论正常退出还是异常退出,Socket都会被正确关闭,避免资源泄漏。

客户端代码注意点

原客户端代码存在几处小问题,建议修正:

  • v_2_init变量未定义,需要提前初始化;
  • 外层while True循环后的break语句位置错误,会导致循环直接终止,建议调整逻辑移除多余的break;
  • 发送数据的注释中有笔误("cent data"应为"send data")。

内容的提问来源于stack exchange,提问作者Yurii Yarema

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 20:20:48