Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c++;如何使用select查看套接字是否已关闭_C++_Linux_Sockets_Select - Fatal编程技术网

C++ c++;如何使用select查看套接字是否已关闭

C++ c++;如何使用select查看套接字是否已关闭,c++,linux,sockets,select,C++,Linux,Sockets,Select,有人能给我举个例子,说明如何使用select()查看客户端是否关闭了套接字上的连接吗 仅供参考。我正在使用linux 谢谢 下面的代码片段首先检查套接字是否标记为可读(关闭时是可读的),然后检查是否有任何内容需要读取 #include <sys/time.h> #include <sys/types.h> #include <unistd.h> #include <sys/ioctl.h> bool isclosed(int sock) {

有人能给我举个例子,说明如何使用select()查看客户端是否关闭了套接字上的连接吗

仅供参考。我正在使用linux


谢谢

下面的代码片段首先检查套接字是否标记为可读(关闭时是可读的),然后检查是否有任何内容需要读取

#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/ioctl.h>

bool isclosed(int sock) {
  fd_set rfd;
  FD_ZERO(&rfd);
  FD_SET(sock, &rfd);
  timeval tv = { 0 };
  select(sock+1, &rfd, 0, 0, &tv);
  if (!FD_ISSET(sock, &rfd))
    return false;
  int n = 0;
  ioctl(sock, FIONREAD, &n);
  return n == 0;
}
#包括
#包括
#包括
#包括
bool已关闭(内部sock){
fd_集rfd;
FD_零(&rfd);
FD_套件(短袜和rfd);
timeval tv={0};
选择(sock+1、&rfd、0、0和tv);
如果(!FD_ISSET(sock和rfd))
返回false;
int n=0;
ioctl(sock、FIONREAD和n);
返回n==0;
}

如果收到读取通知且读取返回0字节,则客户端已完全退出。如果没有,您将收到异常通知。

您不需要执行
select()
,然后执行
ioctl()
。您可以在套接字上进行非阻塞查看,查看它是否返回
0

bool isclosed (int sock) {
    char x;
interrupted:
    ssize_t r = ::recv(sock, &x, 1, MSG_DONTWAIT|MSG_PEEK);
    if (r < 0) {
        switch (errno) {
        case EINTR:     goto interrupted;
        case EAGAIN:    break; /* empty rx queue */
        case ETIMEDOUT: break; /* recv timeout */
        case ENOTCONN:  break; /* not connected yet */
        default:        throw(errno);
        }
    }
    return r == 0;
}
bool已关闭(int sock){
字符x;
打断:
ssize_t r=::recv(sock,&x,1,MSG_DONTWAIT | MSG_PEEK);
if(r<0){
开关(错误号){
案例输入:转到中断;
案例EAGAIN:中断;/*空接收队列*/
案例ETIMEDOUT:中断;/*recv超时*/
案例ENOTCONN:中断;/*尚未连接*/
默认值:throw(errno);
}
}
返回r==0;
}

read在另一端关闭连接时返回0。我正在编写一个telnet服务器,它可以正常工作,但我没有在select中执行“sock+1”。为什么需要这样做?@James:API就是这样定义的。当一个带有
MSG_PEEK
标志的简单的
recv()
可以在一行中完成所有这些操作时。@user207421问题是如何用select检查。这意味着此检查可能是选择多个其他事件的一部分。使用
recv()
并不是这个问题的答案,它是另一个问题的解决方案。客户端已干净地关闭了摘要,或关闭了其输出,或在UNIX或Linux系统上干净地退出,但在Windws系统等系统上则不是,如果不是,您将得到一个错误指示。