Python 套接字编程:recv 和 receivevfrom

问题描述 投票:0回答:3

我是Python和套接字编程的新手,我对

socket.recvfrom()
socket.recv()
的用法感到困惑。据我所知,人们通常使用
recvfrom()
表示 UDP,使用
recv()
表示 TCP。

例如:

serverSocketUDP = socket(AF_INET, SOCK_DGRAM)
serverSocketTCP = socket(AF_INET, SOCK_STREAM)
#... define server...
#...
message, clientAddress = serverSocketUDP.recvfrom(2048) #why 2048 for UDP? Ive seen several examples like this.
message2 = serverSocketTCP.recv(1024) #Again, why 1024 for TCP? 

如上面的例子所示,我感到困惑的是数字。为什么 2048 和 1024 用于不同的协议?这些数字代表什么?

python sockets recv recvfrom
3个回答
20
投票

为什么2048和1024用于不同的协议?

这些数字非常随意,取决于正在实施的协议。即使 TCP 编号有效,您提供的 UDP 编号也很可能是错误的。

TCP 实现了一个流协议,您可以读取任何您想要的大小的块。您可以执行

recv(1)
一次获取一个字节,或者如果您想获取大块,则执行
recv(100000)
recv
可以免费返回您要求的较小块,因此您可能会得到与您想要的不同大小的块。 1024 非常小,您可以毫无问题地读取更大的块。

UDP实现消息协议。您必须请求足够的字节来覆盖整个消息,否则它将被丢弃。该大小取决于协议。协议通常将消息限制为 1500(标准以太网数据包的最大大小),但也可以是最多 65535 的任何内容。请检查实际协议规范以了解最大值。


18
投票

你把它们调换了。 TCP 套接字应使用

socket.recv
,UDP 套接字应使用
socket.recvfrom
。这是因为 TCP 是面向连接的协议。一旦创建连接,它就不会改变。另一方面,UDP 是一种无连接(“发送后忘记”)协议。您使用
recvfrom
以便您知道应该将数据发回给谁。 Recvfrom 不能以同样的方式在 TCP 套接字上工作。

对于1024/2048,这些代表您想要接受的字节数。一般来说,UDP 的开销比 TCP 少,允许您接收更多数据,但这不是一个严格的规则,在这种情况下几乎可以忽略不计。您可以根据需要接收任意数量的信息。 4096 也很常见(对于两者)。


5
投票

我认为人们通常将recvfrom用于UDP。因为在 TCP 中,一旦建立连接,地址信息就不会改变,因此 recvfrom 总是为连接信息字段返回 None。

在上面的代码中,这行会出错:

message2, clientAddress2 = serverSocketTCP.recv(1024)

因为: recvfrom() 返回(数据,连接信息),并且 recv() 仅返回数据。所以它会引发 ValueError 因为你试图解压一个非元组值。

1024 或 2048 只是定义缓冲区大小,但它在返回之前不会等待那么多数据。例如:

#One side, 'receiver' is a socket
receiver.recv(2048)

#Second side, 'sender' is a socket
sender.send('abc'.encode('utf-8'))

显然“sender”发送的数据远小于 2048 字节,但“recv”调用将在收到“sender”发送给它的数据后立即返回

© www.soinside.com 2019 - 2024. All rights reserved.