TCP服务器监测客户端异常退出方法
创始人
2025-05-29 07:04:07
0

        作为服务器必须得具备监测客户端状态得机制,以保证客户端处于不同的状态,服务器进行不同得状态处理,依次来提高实时性,可控性,并且有利于服务器得内存管理。其中客户端得异常处理就属于其中得一种。

        客户端得断开情形无非就两种情况:

        1.客户端能够发送状态给服务器;正常断开,强制关闭客户端等,客户端能够做出反应。

        2.客户端不能发送状态给服务器;突然断网,断电,客户端卡死等,客户端根本没机会做出反应,服务器更不了解客户端状态。

        客户端异常断开的监测手段及使用状态:

方法1:

        getsockopt函数获取套接字状态,根据状态判断客户端的连接情况。

函数原型:

int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
参数:
sockfd:要监测的客户端的套接字
level:协议层次SOL_SOCKET 套接字层次IPPROTO_IP ip层次IPPROTO_TCP TCP层次
option_name:选项的名称(套接字层次)SO_BROADCAST 是否允许发送广播信息SO_REUSEADDR 是否允许重复使用本地地址SO_SNDBUF 获取发送缓冲区长度SO_RCVBUF 获取接收缓冲区长度SO_RCVTIMEO 获取接收超时时间SO_SNDTIMEO 获取发送超时时间
option_value:获取到的选项的值
option_len:value的长度

代码实现:

struct tcp_info info; 
int len=sizeof(info);
getsockopt(client_fd, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len); 
if(info.tcpi_state == TCP_CLOSE_WAIT && info.tcpi_state != TCP_ESTABLISHED)
{printf("Client disconnection!\n");}

        TCP_CLOSE_WAIT:是服务器收到客户端发来的FIN包以后进入的状态,FIN包是客户端断开连接进行四次挥手的第一次挥手,收到 TCP_CLOSE_WAIT状态代表客户端已经想要断开连接或者已经断开连接。

        TCP_ESTABLISHED:表示客户端,服务器双方处于建立连接的状态,可以进行交互,相反则不处于连接状态。

        可以单独使用TCP_CLOSE_WAIT或者TCP_ESTABLISHED状态进行连接状态的监测,我喜欢一起使用。该方法适合客户端断开的第一种情况。

方法2:

        心跳包的实现,心跳包就是服务器定时向客户端发送查询信息,如果客户端有回应就代表连接正常,类似于linux系统的看门狗机制。心跳包的实现有两种:TCP自带的心跳包机制keeplive,和自定义心跳包。

        TCP自带的心跳包:KEEPLIVE保活机制

        使用setsockope函数启动和设置心跳时间的机制:

int RTSP_SESSION::set_keeplive(void)
{int keep_alive = 1;//启动心跳保活机制int keep_idle = 10;
//10s内没收到数据开始发送心跳包int keep_interval = 3;
//每次发送心跳包的时间间隔int keep_count = 3;
//每个3s发送一次心跳包if (setsockopt(client_fd, SOL_SOCKET, SO_KEEPALIVE, &keep_alive, sizeof(keep_alive))){perror("Error setsockopt(SO_KEEPALIVE) failed");return -1;}if (setsockopt(client_fd, IPPROTO_TCP, TCP_KEEPIDLE, &keep_idle, sizeof(keep_idle))){perror("Error setsockopt(TCP_KEEPIDLE) failed");return -1;}if (setsockopt(client_fd, SOL_TCP, TCP_KEEPINTVL, (void *)&keep_interval, sizeof(keep_interval))){perror("Error setsockopt(TCP_KEEPINTVL) failed");return -1;}if (setsockopt(client_fd, SOL_TCP, TCP_KEEPCNT, (void *)&keep_count, sizeof(keep_count))){perror("Error setsockopt(TCP_KEEPCNT) failed");return -1;}return 0;
}

        上述代码的意思就是:10s没收到客户端的数据就开始发送心跳包,如果客户端没回应,则导致client_fd失效,所有调用client_fd的读写函数都会立即返回(read write recv send等),并且错误码是ETIMEDOUT。

        通过判断读写函数的状态就可以判断客户端的连接状态:

int ret = recv(client_fd, buf, len, MSG_PEEK);
if(ret <= 0 && errno == ETIMEDOUT)printf("Client disconnection!\n");
MSG_PEEK:查看缓存内容,但是不从缓存中读取,不会干扰程序的正常读写,可以利用该方法写个线程进行监测,或者直接使用自己读写函数的返回值进行判断。

        自己定义心跳包:

        这个必须是服务器,客户端都是自己写的才可以,在服务器中每隔一段时间向服务器发送一个心跳包,客户端收到后进行回复,心跳包的协议可以自己定,以此监测客户端状态。

        心跳包适合客户端断开的情形1,情形2,都适用。

番外:

        如果使用的是select的话,无论是正常中断还是异常中断,select都会返回1:

ret = select(client_fd+1, &rfd, NULL, &efd, &timeout);
if(ret > 0)
{if (FD_ISSET(client_fd, &rfd) != 0){//客户端中断会进入这里,在这里判断recv状态进行监测if ((ret = recv(client_fd, buf, len, 0)) <= 0){if(errno == ETIMEDOUT){printf("The client is disconnected abnormally. Check the cause!\n");}}}
}

相关内容

热门资讯

黄金史诗级暴跌,原因可能与一纸... 当地时间1月30日,随着美联储前理事凯文·沃什(Kevin Warsh)正式被美国总统特朗普提名为下...
深圳国资七亿下场扫货白石洲? 来源:市场资讯 (来源:深圳房产在线) 最近看到,近日一则消息引发关注,就是今年1月发生一宗白石洲大...
国投智能2025业绩承压 AI... 来源:财联社 财联社1月30日讯(记者 方彦博)2025年,AI应用的商业化落地是众多AI企业面临的...
原创 男... 在爱情的海洋中,星座的波涛有时能揭示出隐藏的情感暗流。当男人在愤怒的风暴中显露出四种迹象时,或许他并...
农业银行董事长谷澍会见英格兰银... 来源:市场资讯 来源:中国农业银行 1月29日,农业银行董事长谷澍会见了英格兰银行副行长兼英国审慎监...
“易中天”,业绩大爆发!需求增... “易中天”2025年度业绩持续爆发! 1月30日晚间,中际旭创发布2025年度业绩预告,预计2025...
双平台战略提速:仙乐健康谋“A... 中国营养健康食品行业的龙头企业仙乐健康,在1月30日向市场投下了一枚重磅消息:公司已正式向香港联交所...
左季庆染指淳厚基金股权纷争为谁... 2026年1月6日,证监会一纸批复核准上海长宁国有资产经营投资有限公司(下称“长宁国资”)成为淳厚基...
上市即巅峰?拉芳家化首度亏损,... 为什么消费端对“拉芳”爱不起来了? 作者 | 方璐 编辑丨于婞 来源 | 野马财经 拉芳家化(603...
原创 黄... 1月31日晚间,英伟达CEO黄仁勋现身中国台湾台北市砖窑古早味怀旧餐厅,宴请了35位与英伟达合作的供...
山西太钢不锈钢股份有限公司 2... 来源:证券日报 证券代码:000825 证券简称:太钢不锈 公告编号:2026-001 本公司及董...
把自己的银行贷款出借给别人,有... 新京报讯(记者张静姝 通讯员邸越洋)因贷款出借后未被归还,原告牛女士将被告杨甲、杨乙诉至法院,要求二...
金价暴跌,刚买的金饰能退吗?有... 黄金价格大跌,多品牌设置退货手续费。 在过去两三天,现货黄金价格经历了“过山车”般的行情,受金价下跌...
预计赚超2500万!“豆腐大王... 图片来源:图虫创意 在经历了一年亏损后,“豆腐大王”祖名股份(003030.SZ)成功实现扭亏为盈。...
特朗普提名“自己人”沃什执掌美... 据新华社报道,当地时间1月30日,美国总统特朗普通过社交媒体宣布,提名美国联邦储备委员会前理事凯文·...
爱芯元智将上市:连年大额亏损,... 撰稿|多客 来源|贝多商业&贝多财经 1月30日,爱芯元智半导体股份有限公司(下称“爱芯元智”,HK...
一夜之间,10只A股拉响警报:... 【导读】深康佳A等10家公司昨夜拉响退市警报 中国基金报记者 夏天 1月30日晚间,A股市场迎来一波...
谁在操控淳厚基金?左季庆为谁趟... 2026年1月6日,证监会一纸批复核准上海长宁国有资产经营投资有限公司(下称“长宁国资”)成为淳厚基...
工商银行党委副书记、行长刘珺会... 人民财讯1月31日电,1月29日,工商银行党委副书记、行长刘珺会见来访的上海电气集团党委书记、董事长...