断开并重新连接的数据报套接字
-
06-09-2019 - |
题
荫试图创建一个基于数据报套接字(UDP)的迭代服务器。 它调用连接到第一客户端,它从第一recvfrom的()调用得到(是的,我知道这是没有真正的连接)。 曾担任该客户端后,我断开UDP套接字(调用connect与AF_UNSPEC) 然后,我打电话recvfrom的(),从一个客户端获得的第一个包。
现在的问题是,recvfrom的()在循环的第二次迭代的调用返回0.我的客户从来没有发送空包,所以有什么可怎么回事。
这是什么荫干(伪代码):
s = socket(PF_INET, SOCK_DGRAM, 0)
bind(s)
for(;;)
{
recvfrom(s, header, &client_address) // get first packet from client
connect(s,client_address) // connect to this client
serve_client(s);
connect(s, AF_UNSPEC); // disconnect, ready to serve next client
}
编辑:我发现了错误在我的客户意外发送空数据包。 现在我的问题是,如何让客户等待得到服务的发送请求到无处(服务器连接到另一个客户端,并且不提供任何其他客户还)代替。
解决方案
连接()是真的完全不必要对SOCK_DGRAM。
调用connect 不阻止你从其他主机接收数据包,也不会阻止你送他们。只是不打扰,这不是真的很有帮助。
修正:是的,显然它并阻止你从其他主机接收数据包。但是,在一个服务器做,这是一个有点傻,因为任何其他客户端将被锁定出来的时候连接()的一个。此外,你还需要搭上“糠”,这四处飘浮。有可能与连接()在DGRAM插座相关的一些竞争条件 - ?如果您调用连接,并从其他主机的数据包都已经在缓冲区发生了什么
另外,0是从recvfrom的()一个有效的返回值,如空(无数据)的数据包是有效的,可以存在(事实上,人们经常使用它们)。所以你不能先确认一下是否成功的方式。
在所有的可能性,一个零字节的数据包是在队列中已
您协议应被工程化以最小化被误解一个错误的数据报的机会;为此我建议您不要使用空数据包,并使用一个神奇的数字来代替。
UDP应用程序必须能识别“糠”分组和滴他们的;他们迟早会转起来。
其他提示
man connect
:
... If the initiating socket is not connection-mode, then connect() shall set the socket’s peer address, and no connection is made. For SOCK_DGRAM sockets, the peer address identifies where all datagrams are sent on subsequent send() functions, and limits the remote sender for subsequent recv() functions. If address is a null address for the protocol, the socket’s peer address shall be reset. ...
万一有人碰到这个stumbples像我一样的修正。断开连接()需要与的sockaddr的上sa_family成员设置为AF_UNSPEC被调用。不刚过AF_UNSPEC。