4

私の C++ アプリケーションでは、UDP ソケットに ::bind() を使用していますが、まれに、接続が失われたために再接続した後、何度も再試行した後でも errno EADDRINUSE が発生します。データを受信する UDP 接続の反対側は正常に再接続され、select() が読み取り対象があることを示すのを待機しています。

これは、ローカルポートが使用されていることを意味すると思います。真の場合、反対側が正常に接続するようにローカルポートをリークしている可能性がありますか? ここでの実際の問題は、反対側が正常に接続されて待機しているのに、こちら側が EADDRINUSE でスタックしていることです。

- 編集 -

これは、問題が発生しているこの UDP ソケットではなく、TCP ソケットで既に SO_REUSEADDR を実行していることを示すコード スニペットです。

// 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));

新しいソケットを作成して再接続する別のコードがある場合は、そのコードにも設定します。これは、OS のデフォルトの動作に関係しています。壊れたソケットのポートは、しばらく機能しなくなります。

[編集] これは UDP 接続には適用されません。ソケットのセットアップに使用するコードを投稿する必要があるかもしれません。

于 2012-04-30T13:38:28.807 に答える