简体   繁体   English

python:调用 socket.recvfrom() 两次

[英]python: invoking socket.recvfrom() twice

I am writing two python scripts to communicate over UDP using python sockets .我正在编写两个 python 脚本以使用 python sockets通过 UDP 进行通信。 Here's the related part of code这是代码的相关部分

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((HOST, PORT))
s.setblocking(True) #I want it to be blocking
#(...)
(msg, addr) = sock.recvfrom(4)
#(...)
(msg2, addr2) = sock.recvfrom(2)

I want the receiving to be blocking and I don't know the size of the whole message before I read the first 4-byte part.我希望接收被阻塞,并且在阅读前 4 个字节部分之前我不知道整个消息的大小。 The above code becomes blocked on the sock.recvrfom(2) part, whereas modified, with one sock.recvfrom instead of two works alright:上面的代码在sock.recvrfom(2)部分被阻塞,而修改后,用一个sock.recvfrom而不是两个可以正常工作:

(msg, addr) = sock.recvfrom(6) #works ok, but isn't enough for my needs

Any idea how I can conveniently read the incoming data in two parts or why the code doesn't work as expected?知道如何方便地分两部分读取传入的数据,或者为什么代码不能按预期工作吗?

socket.recvfrom(size) will (for UDP sockets) read one packet, up to size bytes. socket.recvfrom(size)将(对于 UDP 套接字)读取一个数据包,最多为size个字节。 The excess data is discarded .多余的数据被丢弃 If you want to receive the whole packet, you have to pass a larger bufsize, then process the packet in bits (instead of trying to receive it in bits.)如果要接收整个数据包,则必须传递更大的 bufsize,然后以位为单位处理数据包(而不是尝试以位为单位接收它。)

If you want a more convenient, less fickle interface to network I/O, consider Twisted .如果您想要一个更方便、更少变化的网络 I/O 接口,请考虑Twisted

Read from UDP socket dequeues the whole datagram .从 UDP 套接字读取整个数据报

UDP is a message-based protocol. UDP 是一个基于消息的协议。 recvfrom will read the entire message that was originally sent, but if the buffer isn't big enough, it will throw an exception: recvfrom将读取最初发送的整个消息,但如果缓冲区不够大,它会抛出异常:

socket.error: [Errno 10040] A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself socket.error: [Errno 10040] 在数据报套接字上发送的消息大于内部消息缓冲区或其他网络限制,或者用于接收数据报的缓冲区小于数据报本身

So I am not sure why you would hang on the 2nd recvfrom if a 6-byte message was originally sent.所以我不确定如果最初发送的是 6 字节消息,为什么你会挂在第二个recvfrom上。 You should throw an exception on the first recvfrom .您应该在第一个recvfrom上引发异常。 Perhaps post an actual working, minimal example of the client and the server program.也许发布客户端和服务器程序的实际工作的最小示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM