C++ 检查socket是否连接

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12402549/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:15:09  来源:igfitidea点击:

Check if socket is connected or not

c++csocketsconnection

提问by opc0de

I have an application which needs to send some data to a server at some time. The easy way would be to close the connection and then open it again when I want to send something. But I want to keep the connection open so when I want to send data, I first check the connection using this function:

我有一个应用程序需要在某个时间向服务器发送一些数据。简单的方法是关闭连接,然后在我想发送一些东西时再次打开它。但是我想保持连接打开,所以当我想发送数据时,我首先使用这个函数检查连接:

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

The bad part is that this doesn't work. It hangs when there is no data to receive. What can I do? How can I check if the connection is still open?

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

回答by David Schwartz

Don't check first and then send. It's wasted effort and won't work anyway -- the status can change between when you check and when you send. Just do what you want to do and handle the error if it fails.

不要先检查再发送。这是白费力气,无论如何都行不通——状态可能会在您检查和发送之间发生变化。只要做你想做的事情,如果失败就处理错误。

To check status, use:

要检查状态,请使用:

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

回答by cnicutar

You need to enable non-blocking behavior, by setting O_NONBLOCKusing fcntl. One easy but non-standard way to do a non-blocking read would be to use:

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

recv(sock, &buf, 1, MSG_PEEK | MSG_DONTWAIT);

Afterwards, you mustcheck errno if it fails. It can fail with EAGAINor it can fail with EBADFor ENOTCONNetc.

之后,如果失败,您必须检查 errno。它可能会失败,EAGAIN或者它可能会失败,EBADFENOTCONN等。



Obviously, the simplest and cleanest way to deal with this would be to avoid "forgetting" if the socket is connected or not. You'll notice if the socket becomes disconnected once a recvreturns 0 or a sendreturns EPIPE.

显然,处理这个问题的最简单和最干净的方法是避免“忘记”套接字是否已连接。一旦 arecv返回 0 或 asend返回,您会注意到套接字是否断开连接EPIPE

回答by mark

Default use of TCP doesn't allow very timely detection of dead sockets (outside of normal closure) so I'll suggest that an "is_connected" function like this is largely useless for all practical purposes. Consider implementing an application-layer keep-alive and track if it's alive based on timely responses (or lack thereof).

TCP 的默认使用不允许非常及时地检测死套接字(正常关闭之外),所以我建议像这样的“is_connected”函数对于所有实际目的来说基本上是无用的。考虑实施应用层保持活动并根据及时响应(或缺乏响应)跟踪它是否处于活动状态。

edit: after posting i see BoBTFish's link, which is effectively the same thing.

编辑:发布后我看到了 BoBTFish 的链接,这实际上是同一件事。