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

P2P网络中Socket监听的while循环结束后代码无法执行问题

问题分析与修复方案

你的代码里socket.recvfrom(1024)是阻塞式调用——只要没有客户端发送数据返回,程序就会一直卡在这个调用上等待,哪怕time.time() < end的条件已经不满足。这就是循环无法自动退出、最后一行打印代码永远执行不到的核心原因。

另外注意:原代码缺少import time语句,运行时会直接报错,必须补上。

修复方案一:给Socket设置超时时间

通过给UDP Socket设置超时时间,让recvfrom在指定时间内没收到数据就抛出异常,我们可以捕获异常后继续检查循环是否到期:

from socket import *
import time  # 必须导入time模块

server_socket = socket(AF_INET, SOCK_DGRAM)
server_socket.bind(('', line))  # line为服务器端口号(需是整数)
server_socket.settimeout(1)  # 设置每次recv最多等待1秒
online = []

for p in clients:  # clients为所有客户端地址列表
    server_socket.sendto('ping'.encode(), p)

end = time.time() + 10
while time.time() < end:
    try:
        message, peer = server_socket.recvfrom(1024)
        print('pong ', peer)
        online.append(peer)
    except timeout:
        # 超时后继续判断是否还在10秒窗口内
        continue

# 可选:去重,避免同一客户端多次返回导致重复记录
online = list(set(online))
print('online: ', online)

修复方案二:用select精确控制等待时间

使用select模块监听Socket的可读事件,同时传入剩余的等待时间,这样可以更精准地控制整个循环的10秒时限:

from socket import *
import time
import select

server_socket = socket(AF_INET, SOCK_DGRAM)
server_socket.bind(('', line))
online = []

for p in clients:
    server_socket.sendto('ping'.encode(), p)

end = time.time() + 10
while time.time() < end:
    remaining_time = end - time.time()
    if remaining_time <= 0:
        break
    # 监听Socket是否有数据可读,超时时间为剩余的10秒窗口时间
    ready_sockets, _, _ = select.select([server_socket], [], [], remaining_time)
    if ready_sockets:
        message, peer = server_socket.recvfrom(1024)
        print('pong ', peer)
        online.append(peer)

online = list(set(online))
print('online: ', online)

额外注意事项

  • 如果客户端可能重复发送pong响应,建议用集合存储在线客户端地址,避免重复记录;
  • 确保line是整数类型的端口号,clients是合法的客户端地址元组列表(格式如('192.168.1.100', 8080))。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 17:35:17