ソケット再起動ポートが占有されます
1606 ワード
問題の説明:
コードはlinuxの前のsocketサーバ側で、クライアントは接続を確立します.Ctrl+cはsocketサーバを終了します.サーバーを再起動した後、ポートが占有され、bindが失敗した(Address already in use);約2分後、サーバーを再起動して再利用できます.
問題の分析:
ソケットが終わるとlinuxはこのポートを一定時間保持するので、1~4分だそうです.後で再利用されます.
処理方法:
SO_の設定REUSEADDRオプションでは、この問題を解決できます.socketをオフにすると、すぐにポートを使用できます.コードは次のとおりです.
注意事項:
SO_REUSEADDRの設定の場所はsocketが作成された後、bindの前です.
解析関数でsocketをcloseしても解決できません.Ctrl+cが強制的に終了したため、解析は実行されません.closeが作用するかどうかは不明です.
コードはlinuxの前のsocketサーバ側で、クライアントは接続を確立します.Ctrl+cはsocketサーバを終了します.サーバーを再起動した後、ポートが占有され、bindが失敗した(Address already in use);約2分後、サーバーを再起動して再利用できます.
問題の分析:
ソケットが終わるとlinuxはこのポートを一定時間保持するので、1~4分だそうです.後で再利用されます.
処理方法:
SO_の設定REUSEADDRオプションでは、この問題を解決できます.socketをオフにすると、すぐにポートを使用できます.コードは次のとおりです.
int Socket_base::SocketInit(void)
{
int serverSocketFd = -1;
int serverLen = 0;
struct sockaddr_in serverAddress; // sockaddr_in for AF_INET
/* Create and name a socket for the server. */
m_serverSocketFd = socket(AF_INET, SOCK_STREAM, 0);
// use SO_REUSEADDR, so may use the port again immediately after restarting the socket
int optval = 1;
if (setsockopt(m_serverSocketFd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0)
{
perror("setsockopt error");
}
int flags = fcntl(m_serverSocketFd, F_GETFL, 0); // get file flag
fcntl(m_serverSocketFd, F_SETFL, flags | O_NONBLOCK); // set file Non-blocking, for "accept" use in while
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddress.sin_port = htons(SOCKET_PORT);
serverLen = sizeof(serverAddress);
if((bind(m_serverSocketFd, (struct sockaddr *)&serverAddress, serverLen)) < 0)
{
perror("bind error");
}
/* Create a connection queue and initialize readFds to handle input from serverSocketFd. */
listen(m_serverSocketFd, 0);
}
注意事項:
SO_REUSEADDRの設定の場所はsocketが作成された後、bindの前です.
解析関数でsocketをcloseしても解決できません.Ctrl+cが強制的に終了したため、解析は実行されません.closeが作用するかどうかは不明です.