C++ 检查插座是否已连接

C++ 检查插座是否已连接,c++,c,sockets,connection,C++,C,Sockets,Connection,我有一个应用程序,需要在某个时间向服务器发送一些数据。最简单的方法是关闭连接,然后在我想发送内容时再次打开。但我想保持连接打开,因此当我想发送数据时,我首先使用以下功能检查连接: bool is_connected(int sock) { unsigned char buf; int err = recv(sock,&buf,1,MSG_PEEK); return err == -1 ? false : true; } 糟糕的是这不起作用。当没有数据可接收时,它

我有一个应用程序,需要在某个时间向服务器发送一些数据。最简单的方法是关闭连接,然后在我想发送内容时再次打开。但我想保持连接打开,因此当我想发送数据时,我首先使用以下功能检查连接:

bool is_connected(int sock)
{
    unsigned char buf;
    int err = recv(sock,&buf,1,MSG_PEEK);
    return err == -1 ? false : true;
}

糟糕的是这不起作用。当没有数据可接收时,它将挂起。我能做什么?如何检查连接是否仍然打开

您需要通过使用
fcntl
设置
O_NONBLOCK
来启用非阻塞行为。进行非阻塞读取的一种简单但非标准的方法是使用:

recv(sock, &buf, 1, MSG_PEEK | MSG_DONTWAIT);
之后,如果失败,您必须检查errno。它可以通过
EAGAIN
失败,也可以通过
EBADF
ENOTCONN
等失败



显然,处理这个问题最简单、最干净的方法是避免“忘记”是否连接了套接字。您会注意到,如果一旦
recv
返回0或
send
返回
EPIPE
,默认情况下,TCP的使用不允许非常及时地检测死套接字(正常关闭之外),那么我建议像这样的“已连接”函数对于所有实际用途都是无用的。考虑实现一个应用程序层,保持它的活力并跟踪它是否基于及时的响应(或者缺少它)活着。
编辑:发布后,我看到了BoBTFish的链接,实际上也是一样。

不要先检查然后发送。这是白费力气,而且无论如何也不会起作用——在您检查和发送时,状态可能会发生变化。只要做你想做的事情,如果失败了就处理错误

要检查状态,请使用:

int error_code;
int error_code_size = sizeof(error_code);
getsockopt(socket_fd, SOL_SOCKET, SO_ERROR, &error_code, &error_code_size);

这不会检测到所有连接故障。只有send()才能做到这一点。@EJP事实上是这样的。我只是在改进op的解决方案。你所建议的是唯一的防弹解决方案,但它需要发送。真的。。。但有时检查插座是否仍然连接很有用。将其设置为非块,然后使用peek_msg读取是一种很好的方法,可以获取错误代码,检查套接字是否仍然连接。@Rafaelbatista为什么?使用它将检查。由于David在上面给出的原因,首先测试无法可靠地工作。@EJP:我想检查客户机连接是否处于活动状态,以便在不处于活动状态时不会浪费资源。@che是的,所以请使用它进行检查。如果它不存在,你可以停止浪费资源。检查本身是对资源的浪费。@seth,您可以使用它来执行此操作。