问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何判断socket已经断开

发布网友 发布时间:2022-04-28 12:02

我来回答

1个回答

热心网友 时间:2023-10-08 21:21

非阻塞模式,如果暂时没有数据,返回的值也会是<=0的,如果用阻塞模式的话,返回<=0的值是可以认为socket已经无效了。

当使用 select()函数测试一个socket是否可读时,如果select()函数返回值为1,
且使用recv()函数读取的数据长度为0 时,就说明该socket已经断开。

经过代码试验,如果进程受到一些信号时,例如:EINTR,recv()返回值小于等于0时,这是就需要判断 errno是否等于 EINTR ,
如果errno == EINTR 则说明recv函数是由于程序接收到信号后返回的,socket连接还是正常的,不应close掉socket连接。

如果write,我觉得还有一些情况需要考虑,那就是写的太快的时候,有可能buffer写满了,这是,errno是EAGAIN,可以根据实际需要,如果errno是EAGAIN的话,再写几次。

当然,read的时候也有类似write的情况,需要check一下errno,如果是EAGAIN或者EINTR,最好不要立刻终止操作,再尝试一下!

这是我写的一个代码!

int SocketConnected(int sock)
{
int res,recvlen;
char buf[20] = {'\0'};
struct timeval timeout={3,0};
fd_set rdfs;
FD_ZERO(&rdfs);
FD_SET(sock,&rdfs);

res = select(sock+1,&rdfs,NULL,NULL,&timeout);

if(res > 0){

recvlen = recv(sock,buf,sizeof(buf),0);
if(recvlen > 0){
printf("socket connected\n");
return 1;
} else if (recvlen < 0 ){
if(errno == EINTR){
printf("socket connected\n");
return 1;
}else {
printf("socket disconnected! connect again!\n");
return 0;
}
} else if (recvlen == 0){
printf("socket disconnected!connect again\n");
return 0;
}
} else if(res == 0 ){
//time out
printf("socket connected\n");
return 1;
} else if(res < 0){
if (errno == EINTR){
printf("socket connected\n");
return 1;
}else{
printf("socket disconnected ! connect again!\n");
return 0;
}
}
return 0;
}

另外还有另外一种检测方法,也比较好用,但是在2.4内核在编译过程中可能有问题。

头文件 Linux/tcp.h、

int SocketConnected(int sock)
346 {
347 struct tcp_info info;
348 int len=sizeof(info);
349 if(sock<=0){
350 return 0;
351 }
352 memset(&info,0,sizeof(info));
353 getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len);
354 if(info.tcpi_state== 1) {
355 printf("socket connected\n");
356 return 1;
357 } else {
358 printf("socket disconnected\n");
359 return 0;
360 }
361 }

热心网友 时间:2023-10-08 21:21

非阻塞模式,如果暂时没有数据,返回的值也会是<=0的,如果用阻塞模式的话,返回<=0的值是可以认为socket已经无效了。

当使用 select()函数测试一个socket是否可读时,如果select()函数返回值为1,
且使用recv()函数读取的数据长度为0 时,就说明该socket已经断开。

经过代码试验,如果进程受到一些信号时,例如:EINTR,recv()返回值小于等于0时,这是就需要判断 errno是否等于 EINTR ,
如果errno == EINTR 则说明recv函数是由于程序接收到信号后返回的,socket连接还是正常的,不应close掉socket连接。

如果write,我觉得还有一些情况需要考虑,那就是写的太快的时候,有可能buffer写满了,这是,errno是EAGAIN,可以根据实际需要,如果errno是EAGAIN的话,再写几次。

当然,read的时候也有类似write的情况,需要check一下errno,如果是EAGAIN或者EINTR,最好不要立刻终止操作,再尝试一下!

这是我写的一个代码!

int SocketConnected(int sock)
{
int res,recvlen;
char buf[20] = {'\0'};
struct timeval timeout={3,0};
fd_set rdfs;
FD_ZERO(&rdfs);
FD_SET(sock,&rdfs);

res = select(sock+1,&rdfs,NULL,NULL,&timeout);

if(res > 0){

recvlen = recv(sock,buf,sizeof(buf),0);
if(recvlen > 0){
printf("socket connected\n");
return 1;
} else if (recvlen < 0 ){
if(errno == EINTR){
printf("socket connected\n");
return 1;
}else {
printf("socket disconnected! connect again!\n");
return 0;
}
} else if (recvlen == 0){
printf("socket disconnected!connect again\n");
return 0;
}
} else if(res == 0 ){
//time out
printf("socket connected\n");
return 1;
} else if(res < 0){
if (errno == EINTR){
printf("socket connected\n");
return 1;
}else{
printf("socket disconnected ! connect again!\n");
return 0;
}
}
return 0;
}

另外还有另外一种检测方法,也比较好用,但是在2.4内核在编译过程中可能有问题。

头文件 Linux/tcp.h、

int SocketConnected(int sock)
346 {
347 struct tcp_info info;
348 int len=sizeof(info);
349 if(sock<=0){
350 return 0;
351 }
352 memset(&info,0,sizeof(info));
353 getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len);
354 if(info.tcpi_state== 1) {
355 printf("socket connected\n");
356 return 1;
357 } else {
358 printf("socket disconnected\n");
359 return 0;
360 }
361 }
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
玉米仁子饭产自哪里 中国期货交易所的交易品种有哪些? 历史要怎么读,有啥诀窍 高中历史诀窍 年终会活动策划方案 深度解析:第一财经回放,探索财经新风向 逆水寒手游庄园怎么邀请好友同住 逆水寒手游 逆水寒不同区可以一起组队吗? 逆水寒手游 逆水寒怎么进入好友世界? 逆水寒手游 逆水寒怎么去别人的庄园? fork的分叉函数 在css中background-attachment: fixed的意思是啥 EACCES or EAGAIN 在哪个头文件 刚学多线程的一点小问题 lockf 函数的用法 通信的方式有多种,假设需要在Linux系 谁知道&lt;fcnt1.h&gt;起什么作用? linux的头文件中是否有writeError函数? 谁给我解释下fcntl.h头文件,拭目以待! 如何对读写锁进行处理 如果修改QQ密码时忘了问题怎么办? QQ改密码忘记了怎么办 丰田凯美瑞一键启动正确用法? 修改qq密码忘记以前密码了怎么办 一键启动的,怎么样正确启动,熄火 QQ修改密码后忘记了,怎么办 ETF基金如何购买呢?在哪里购买呢?求大侠指点,我想买些 汽车如何一键启动?汽车正确一键启动步骤? 请问一下如何购买etf基金? 一键启动的正确操作方法是什么? 如何测试创建线程的开销的数量级 如何使用Go建开发高负载WebSocket服务器 高手进,关于C语言在windows上建立多线程的问题(VC6.0上实现) C语言中unix_error在哪个头文件中? 信号量,互斥锁,读写锁和条件变量的区别 线程同步:何时互斥锁不够,还需要条件变量 表示不能在一起的伤感句子有哪些? 不能在一起心酸的句子 不能在一起心酸的句子有哪些? 爱一个人,却又不能在一起的伤感段落 表现一对男女互相爱慕但又不能在一起的句子 最好是伤感点的 形容想念一个人又不能在一起的句子 表达俩人不能在一起无奈的句子 因为某种原因两个人不能在一起的伤感语句 伤感相爱不能在一起的句子 形容“相遇不能在一起”的句子有哪些? 在酒吧相识你但又不能在一起的伤感句子 怎么安装宣传栏? 不锈钢宣传栏安装有哪几种方法 十五米宣传栏的水平怎么找