7

クライアントがselect()関数で切断されたときはいつでも検出しようとしています。問題は、 select() がどのように機能するかをよく理解していないことです。私は次のコードを使用しています。何が間違っているのか、クライアントが切断されているかどうかを検出する方法を教えてください。ノンブロッキングソケットを使用しています。

int Network::bytesAvailable()
{
    long bytes = 0;

    if(ioctl(this->sockfd, FIONREAD, &bytes) < 0)
    {
        printf("ERROR: Network:bytesAvailable: ioctl() call failed.\n");
        return -1;
    }

    return bytes;
}

NetworkStatus Network::status()
{
    struct timeval tv;
    fd_set  fd;
    int result = 0;

    tv.tv_sec  = 5;
    tv.tv_usec = 0;

    FD_ZERO(&fd);
    FD_SET(this->sockfd, &fd);

    result = select(this->sockfd + 1, &fd, 0, 0, &tv);

    if(result && !this->bytesAvailable())
    {
        return -1; // disconnected, I'm guessing this is definitely WRONG.
    }
    else if(result > 0 && FD_ISSET(this->sockfd, &fd))
    {
        return 1; // bytes available.
    }
    else if(!result)
    {
        return 0; // timeout
    }

    return -1; // select() call failed.
}
4

1 に答える 1

11

ソケットが閉じると「読み取り可能」になりますが、呼び出すrecvと 0 バイトが返されます。使用selectすると、ソケットがいつ読み取れるかrecvがわかります。次に、ソケットを読み取るときに0が返された場合、ソケットが閉じていることがわかります。

あなたのコメント「利用可能なバイト数」は正確ではありません。ただし、ソケットから読み取ることはできますが、閉じている場合は使用可能なバイトがありません。

else if(result > 0 && FD_ISSET(this->sockfd, &fd))
{
    return 1; // bytes available.
}

ノンブロッキング ソケットでは、データがなくソケットが閉じられていない場合はrecv-1 を返し、 (または) に設定errnoします。EWOULDBLOCKEAGAIN

于 2013-07-23T18:19:45.237 に答える