4

在我的 C++ 应用程序中,我将 ::bind() 用于 UDP 套接字,但在极少数情况下,由于连接丢失而重新连接后,即使重试多次,我也会收到 errno EADDRINUSE。将接收数据的 UDP 连接的另一端重新连接良好并等待 select() 指示有要读取的内容。

我想这意味着本地端口正在使用中。如果为真,我怎么会泄漏本地端口,以便另一端可以正常连接?这里真正的问题是另一端连接正常并且正在等待,但这一端卡在 EADDRINUSE 上。

- 编辑 -

这是一个代码片段,显示我已经在我的 TCP 套接字上执行 SO_REUSEADDR,而不是在我遇到问题的这个 UDP 套接字上:

// According to "Linux Socket Programming by Example" p. 319, we must call
// setsockopt w/ SO_REUSEADDR option BEFORE calling bind.
// Make the address is reuseable so we don't get the nasty message.
int so_reuseaddr = 1; // Enabled.
int reuseAddrResult
  = ::setsockopt(getTCPSocket(), SOL_SOCKET, SO_REUSEADDR, &so_reuseaddr,
                 sizeof(so_reuseaddr));

这是我完成后关闭 UDP 套接字的代码:

void
disconnectUDP()
{
  if (::shutdown(getUDPSocket(), 2) < 0) {
    clog << "Warning: error during shutdown of data socket("
         << getUDPSocket() << "): " << strerror(errno) << '\n';
  }
  if (::close(getUDPSocket()) < 0 && !seenWarn) {
    clog << "Warning: error while closing data socket("
         << getUDPSocket() << "): " << strerror(errno) << '\n';

  }
}
4

2 回答 2

5

是的,这很正常。您需要SO_REUSEADDR在绑定之前设置套接字,例如在 *nix 上:

int sock = socket(...);

int yes = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));

如果您有通过创建新套接字重新连接的单独代码,请将其也设置在该套接字上。这只是与操作系统的默认行为有关——损坏的套接字上的端口会暂时失效。

[编辑] 这不应该适用于 UDP 连接。也许您应该发布用于设置套接字的代码。

于 2012-04-30T13:38:28.807 回答
2

在 UDP 中没有失去连接这样的事情,因为没有连接。您可能会丢失已发送的数据包,仅此而已。

不要重新连接,只需重用现有的fd.

于 2012-04-30T14:24:57.423 回答