我是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 用于不同的协议?这些数字代表什么?
为什么2048和1024用于不同的协议?
这些数字非常随意,取决于正在实施的协议。即使 TCP 编号有效,您提供的 UDP 编号也很可能是错误的。
TCP 实现了一个流协议,您可以读取任何您想要的大小的块。您可以执行
recv(1)
一次获取一个字节,或者如果您想获取大块,则执行 recv(100000)
。 recv
可以免费返回您要求的较小块,因此您可能会得到与您想要的不同大小的块。 1024 非常小,您可以毫无问题地读取更大的块。
UDP实现消息协议。您必须请求足够的字节来覆盖整个消息,否则它将被丢弃。该大小取决于协议。协议通常将消息限制为 1500(标准以太网数据包的最大大小),但也可以是最多 65535 的任何内容。请检查实际协议规范以了解最大值。
你把它们调换了。 TCP 套接字应使用
socket.recv
,UDP 套接字应使用 socket.recvfrom
。这是因为 TCP 是面向连接的协议。一旦创建连接,它就不会改变。另一方面,UDP 是一种无连接(“发送后忘记”)协议。您使用 recvfrom
以便您知道应该将数据发回给谁。 Recvfrom 不能以同样的方式在 TCP 套接字上工作。
对于1024/2048,这些代表您想要接受的字节数。一般来说,UDP 的开销比 TCP 少,允许您接收更多数据,但这不是一个严格的规则,在这种情况下几乎可以忽略不计。您可以根据需要接收任意数量的信息。 4096 也很常见(对于两者)。
我认为人们通常将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”发送给它的数据后立即返回