You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动