Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
recv和recvfrom,使用python进行套接字编程_Python_Sockets - Fatal编程技术网

recv和recvfrom,使用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

我不熟悉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 = 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
没有提到字节。