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

linux socket怎么检测断开

发布网友 发布时间:2022-04-25 02:32

我来回答

1个回答

热心网友 时间:2023-01-22 12:31

我想通过recv和send的返回值来判断是否连接异常,但是不成功,下面是我的测试代码,连接成功后如果我断开客户端,那么服务端不会打印错误信息而是等待几秒后直接终止;如果断开服务端,客户端的recv不再阻塞,而且返回值一直是0,请高手指点。

C/C++ code//服务端
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#define MYPORT 3490 /*定义用户连接端口*/
#define BACKLOG 10 /*多少等待连接控制*/
int main(int argc, char *argv[])
{
int sockfd, new_fd;/* listen on sock_fd, new connection on new_fd*/
struct sockaddr_in my_addr; /* my address information */
struct sockaddr_in their_addr; /* connector's address information */
int sin_size;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket");
exit(1);
}

int opt = 1;
int len = sizeof(opt);
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, len);

my_addr.sin_family = AF_INET; /* host byte order */
my_addr.sin_port = htons(MYPORT); /* short, network byte order */
my_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */
bzero(&(my_addr.sin_zero),0); /* zero the rest of the struct */

if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))== -1)
{
perror("bind");
exit(1);
}
if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}

while(1) { /* main accept() loop */
sin_size = sizeof(struct sockaddr_in);
printf("while\n");
if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1)
{
perror("accept");
continue;
}
printf("server: got connection from %s\n", inet_ntoa(their_addr.sin_addr));

while(1)
{
usleep(10000000);
if (send(new_fd, "Hello, world!\n", 14, 0) == -1)
perror("send");
}
close(new_fd);
exit(0);

}
return 0;
}

C/C++ code//客户端
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netdb.h>
#define PORT 3490 /* 客户机连接远程主机的端口 */
#define MAXDATASIZE 100 /* 每次可以接收的最大字节 */
int main(int argc, char *argv[])
{
int sockfd, numbytes;
char buf[MAXDATASIZE];
struct hostent *he;
struct sockaddr_in their_addr; /* connector's address information */
if (argc != 2)
{
fprintf(stderr,"usage: client hostname\n");
exit(1);
}
if ((he=gethostbyname(argv[1])) == NULL)
{ /* get the host info */
herror("gethostbyname");
exit(1);
}

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket");
exit(1);
}

their_addr.sin_family = AF_INET; /* host byte order */
their_addr.sin_port = htons(PORT); /* short, network byte order */
their_addr.sin_addr = *((struct in_addr *)(he->h_addr));
bzero(&(their_addr.sin_zero),0); /* zero the rest of the struct */
if (connect(sockfd, (struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == -1)
{
perror("connect");
exit(1);
}
while(1)
{
printf("receiving......\n");
if ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) == -1)
{
perror("recv");
exit(1);
}
buf[numbytes] = '\0';
printf("Received: %s\n",buf);
}
close(sockfd);
return 0;
}

另外,在网上看到一种利用TCP协议栈中的KeepAlive探测的方法,下面是我从网上找的用的比较多的一段代码,这里应该只是设置了一些属性参数,但不知具体怎样在通信中检测断开,请高手赐教。
C/C++ code#include
……
////KeepAlive实现
//下面代码要求有ACE,如果没有包含ACE,则请把用到的ACE函数改成linux相应的接口
int keepAlive = 1;//设定KeepAlive
int keepIdle = 5;//开始首次KeepAlive探测前的TCP空闭时间
int keepInterval = 5;//两次KeepAlive探测间的时间间隔
int keepCount = 3;//判定断开前的KeepAlive探测次数

if(setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,(void*)&keepAlive,sizeof(keepAlive)) == -1)
{
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("(%P|%t) setsockopt SO_KEEPALIVE error!\n")));

}

if(setsockopt(s,SOL_TCP,TCP_KEEPIDLE,(void *)&keepIdle,sizeof(keepIdle)) == -1)
{
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("(%P|%t) setsockopt TCP_KEEPIDLE error!\n")));
}

if(setsockopt(s,SOL_TCP,TCP_KEEPINTVL,(void *)&keepInterval,sizeof(keepInterval)) == -1)
{
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("(%P|%t) setsockopt TCP_KEEPINTVL error!\n")));
}

if(setsockopt(s,SOL_TCP,TCP_KEEPCNT,(void *)&keepCount,sizeof(keepCount)) == -1)
{
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("(%P|%t)setsockopt TCP_KEEPCNT error!\n")));
}
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
狗狗更加忠诚护家、善解人意,养一只宠物陪伴自己,泰迪能长多大... 描写泰迪狗的外形和特点的句子 国外留学有用吗 花钱出国留学有用吗 !这叫什么号 百万医疗赔付后是否可以续保 前一年理赔过医疗险还能续保吗? 医疗住院险理赔后还能购买吗? 女生多大后可以不在长身高? 如何不用软件把手机投屏到电脑上手机屏幕怎样投放到电脑上 小墨的木筏求生游戏在什么地方下载 心上人,人心上,我若在心上,后面怎么接? 克雷洛夫寓言花的寓意是什么? 在LINUX中keepAlive是什么意思 我写的爱情诗,请欣赏! 寄心上人 心上人啊! 我很爱你! 你可知我的心, 如星辰环绕月亮, 如 求游戏raft下载,苹果电脑的版本!! 克雷洛夫寓言的作者简介 在哪里可以下载电脑版的木筏求生就是二狗子玩的那种的 克雷洛夫寓言中的小匣子的告诉我们什么道理 如何判断Socket的实时连接 木筏求生电脑的下载地址 歌词求歌名:几多春夏秋冬,几多夜雾蒙蒙,心上人,你可知道。。。。。。。。。。。。。。。。 克雷洛夫的名言 第1-18届世界杯总积分排行榜? 心上人是什么意思啊 java.util.Socket类中的setKeepAlive()方法是什么意思 木筏求生电脑版怎么下载 克雷洛夫寓言读后感 心上人的心上,住着我的心上人? 平板电脑怎么下载木筏求生 世界杯女排积份如何算 木筏求生正版在哪下载,,手机电脑都行 世界杯积分怎样算? 怎么下载木筏求生破解中文版 歌词 啊!心上人重逢在那春秋是哪首歌的词 nodejs socket.setKeepAlive是自动检测死链的吗 PC端作为客户端 安卓手机作为服务器 通过USB连接使用socket通讯问题 Kubernetes和Mesos有啥区别,我该使用哪个好 木筏求生怎么下载岛屿 如何添加keepalive 世界杯的积分规则是怎样的? 木筏求生如何下载 Apache的Mesos和Google的Kubernetes 有什么区别 世界杯小组赛中,两队积分一样,计算什么分出名次? 2g在电脑上下载木筏求生够吗 raft怎么加入好友世界 raft联机可以多少个人? 1981年女排世界杯的积分排名 什么软件可以下载木筏求生和荒岛求生的游戏 kubernetes工作方向 有前途吗