荫试图创建一个基于数据报套接字(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。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top