私の 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';
}
}