C++ c++;如何使用select查看套接字是否已关闭
有人能给我举个例子,说明如何使用select()查看客户端是否关闭了套接字上的连接吗 仅供参考。我正在使用linuxC++ 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) {
谢谢 下面的代码片段首先检查套接字是否标记为可读(关闭时是可读的),然后检查是否有任何内容需要读取
#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系统等系统上则不是,如果不是,您将得到一个错误指示。