Python UDP Socket持续发送数据仅接收首条问题求助
问题分析与解决方案
你的UDP收发程序之所以只能收到第一条数据,核心是两个关键问题导致的:
1. 发送端被recvfrom阻塞,后续发送无法执行
在SendSocket函数里,你发送数据后调用了UDPSocket.recvfrom(bufferSize),但接收端完全没有发送回复的逻辑。这就导致发送端在第一次发送后,会一直卡在recvfrom步骤等待回复,后面两次循环的SendSocket调用根本没机会执行。
2. 接收端没有持续监听,仅执行一次接收
接收端只定义了ReceiveSocket函数,但没有循环调用它,所以程序只会执行一次接收操作,拿到第一条数据后就停止运行了,不会继续监听后续的UDP数据包。
修改后的代码
发送端(send文件)
如果你的业务不需要接收回复,直接移除阻塞的recvfrom相关代码即可:
import socket import pickle # 请替换为你实际使用的端口值 LocalReadPort = 1234 EnginePort = 5678 UDPSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) bufferSize = 1024 def SendSocket(Packet, Port): global UDPSocket global bufferSize print('Sending data...') AddressPort = ("127.0.0.2", Port) UDPSocket.sendto(Packet, AddressPort) # 移除不需要的recvfrom代码,避免阻塞后续发送 # msgFromDestination= UDPSocket.recvfrom(bufferSize) # msg = "Message from Server {}".format(pickle.loads(msgFromDestination[0])) # print(msg) def HD(): for i in range(0,3): SendSocket(pickle.dumps(i), EnginePort) print(f'Sent packet {i}') while True: HD()
接收端(receive文件)
添加循环逻辑,让程序持续监听UDP端口:
import socket import pickle # 和发送端保持一致的端口值 EnginePort = 5678 UDPSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) AddressPort = ("127.0.0.2", EnginePort) bufferSize = 1024 UDPSocket.bind(AddressPort) print("UDP server up and listening") def ReceiveSocket(): global UDPSocket global bufferSize bytesAddressPair = UDPSocket.recvfrom(bufferSize) print('Received a packet') message = pickle.loads(bytesAddressPair[0]) address = bytesAddressPair[1] clientMsg = "Message from Client:{}".format(message) clientIP = "Client IP Address:{}".format(address) print(clientMsg) print(clientIP) # 循环调用,持续接收数据 while True: ReceiveSocket()
测试效果
修改后先启动接收端,再运行发送端,你会看到接收端输出类似内容:
UDP server up and listening Received a packet Message from Client:0 Client IP Address:('127.0.0.1', 57742) Received a packet Message from Client:1 Client IP Address:('127.0.0.1', 57742) Received a packet Message from Client:2 Client IP Address:('127.0.0.1', 57742) ...
如果你的业务确实需要发送端接收回复,只需在接收端的ReceiveSocket函数里添加回复逻辑即可,比如:
# 在接收端处理完消息后添加回复代码 reply_msg = pickle.dumps(f"Success received {message}") UDPSocket.sendto(reply_msg, address)
这样发送端的recvfrom就能收到回复,不会阻塞后续发送流程。
内容的提问来源于stack exchange,提问作者Mohammad Razmara




