recv和recvfrom,使用python进行套接字编程
我不熟悉python,也不熟悉套接字编程 我对recv和recvfrom,使用python进行套接字编程,python,sockets,Python,Sockets,我不熟悉python,也不熟悉套接字编程 我对socket.recvfrom()和socket.recv() 我知道通常对于UDP,人们使用recvfrom(),对于TCP,人们使用recv() 比如说, serverSocketUDP = socket(AF_INET, SOCK_DGRAM) serverSocketTCP = socket(AF_INET, SOCK_STREAM) #... define server... #... message, clientAddress = se
socket.recvfrom()
和socket.recv()
我知道通常对于UDP,人们使用recvfrom()
,对于TCP,人们使用recv()
比如说,
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用于不同的协议?这些数字代表什么?请解释一下。我希望我说得够清楚了。谢谢。我认为人们通常使用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'))
显然,“发送方”发送的数据远小于2048字节,但“recv”呼叫在收到从“发送方”发送的数据后会立即返回。您切换了这些数据。TCP套接字应使用
socket.recv
,UDP套接字应使用socket.recvfrom
。这是因为TCP是一种面向连接的协议。一旦创建了连接,它就不会更改。另一方面,UDP是一种无连接(“发送并忘记”)协议。您可以使用recvfrom
,这样您就知道应该向谁发回数据。Recvfrom在TCP套接字上的工作方式不同
对于1024/2048,这些表示您希望接受的字节数。一般来说,UDP的开销比TCP小,允许您接收更多的数据,但这不是严格的规则,在这种情况下几乎可以忽略不计。你可以得到你想要的多或少。4096也很常见(两者都有)。为什么2048和1024适用于不同的协议
这些是非常任意的数字,取决于正在实施的协议。即使TCP号码有效,您提供的UDP号码也很可能是错误的
TCP实现了一个流协议,您可以在任何大小的块中读取它。您可以执行recv(1)
一次获取一个字节,或者recv(100000)
如果您想要获取大数据块recv
可以自由返回您要求的较小块,因此您可能会得到不同于您想要的大小。1024非常小,您可以毫无问题地读取更大的块
UDP实现了一个消息协议。您必须请求足够的字节来覆盖整个消息,否则它将被删除。大小取决于协议。协议将消息限制在1500(标准以太网数据包的最大大小)是很常见的,但它可以是65535。检查实际的协议规格以获得最大值。很好的解释!非常感谢。FWIW,我一直在使用65536字节来侦听UDP套接字上发送的日志,我一直担心边界处的日志,例如,从65530字节开始的日志条目(将从该窗口中消失)。根据您的解释,我将在recvfrom()调用中得到一条UDP消息。这是否意味着我不应该担心掉日志,我是一个白痴,这样想(直到现在)?我可以回答第二个问题,但您能否确认前面的第一个问题?@0xc0de-只要它是基于消息的协议,如UDP,
recvfrom
只获取一条由sendto
发送的消息。假设服务器为每个UDP消息发送一条日志消息,并且不在其一侧跨UDP消息,则无需担心。您可以接收任意多或任意少的消息-至少对于UDP,这不是事实,其中最大数据包大小为2^16=65536
字节。当然,您可以收到任意数量的邮件,尽管:-)非常混乱。在处理DNS UDP(数据报)时,我一直在使用recvfrom(1024)并收到大小介于1024和4096之间的数据。所以在那个用例中,参数似乎只是一个提示?在python文档中,recv
表示buffsize字节的最大值,但是recvfrom
没有提到字节。