C++ 使用select()检测何时断开套接字连接

C++ 使用select()检测何时断开套接字连接,c++,c,sockets,C++,C,Sockets,我正在尝试检测客户机何时与select()函数断开连接。问题是,我不太明白select()是如何工作的。我正在使用以下代码,您能告诉我我做错了什么和/或如何检测客户端是否断开连接吗? 我使用的是非阻塞套接字 int Network::bytesAvailable() { long bytes = 0; if(ioctl(this->sockfd, FIONREAD, &bytes) < 0) { printf("ERROR: Netw

我正在尝试检测客户机何时与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.
}
int网络::字节可用()
{
长字节=0;
if(ioctl(this->sockfd、FIONREAD和bytes)<0)
{
printf(“错误:网络:字节可用:ioctl()调用失败。\n”);
返回-1;
}
返回字节;
}
网络状态网络::状态()
{
结构时间值电视;
fd_集fd;
int结果=0;
tv.tv_sec=5;
tv.tv_usec=0;
FD_零(&FD);
FD_集合(此->sockfd和&FD);
结果=选择(此->sockfd+1和fd、0、0和tv);
if(result&!this->bytesavable())
{
return-1;//断开连接,我猜这肯定是错误的。
}
else if(结果>0&&FD_设置(此->sockfd,&FD))
{
返回1;//可用字节。
}
否则,如果(!结果)
{
返回0;//超时
}
return-1;//select()调用失败。
}

当套接字关闭时,它将变得“可读”,但调用
recv
将返回0字节。使用
select
可以判断何时可以读取套接字,然后在读取套接字时,如果
recv
返回0,则您知道它已关闭

你的评论“可用字节数”并不准确。套接字可以从中读取,但是,如果它关闭,将没有可用的字节

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

在非阻塞套接字中,如果没有数据且套接字未关闭,
recv
将返回-1,并将
errno
设置为
ewoodblock
(或
EAGAIN
)。

通常我们会检测连接是否处于活动状态?使用
keepalive
select()
我们用于多路复用。不正确吗?我不懂你的语法,对不起:)对不起,我的英语很差:(但我编辑了评论,现在明白了吗?不,我真的很抱歉:)在非阻塞套接字上,它不正确,因为recv可以返回0(还没有收到数据)。