TCP长连接建立完成后,我们通常需要检测网络的连接状态,以反馈给客户做响应的处理。通过设置TCP keepalive的属性,打开socket的keepalive属性,并设置发送底层心跳包的时间间隔。TCP/IP五层网络模型,我们调用socket等接口是应用层的函数,TCP keepalive是在底层定时发送心跳报文,服务器端接收到底层的心跳报文直接丢弃,不关心其内容。

以下是windows下TCP keepalive设置的函数:

#include <mstcpip.h>
int CClientCtrl::socket_tcp_alive(int socket)
{
int ret = 0; int keep_alive = 1; ret = setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, (char*)&keep_alive, sizeof(keep_alive)); if (ret == SOCKET_ERROR) { printf("setsockopt failed: %d \n", WSAGetLastError()); return -1; } struct tcp_keepalive in_keep_alive = {0}; unsigned long ul_in_len = sizeof(struct tcp_keepalive); struct tcp_keepalive out_keep_alive = {0}; unsigned long ul_out_len = sizeof(struct tcp_keepalive); unsigned long ul_bytes_return = 0; in_keep_alive.onoff = 1; /*打开keepalive*/ in_keep_alive.keepaliveinterval = 5000; /*发送keepalive心跳时间间隔-单位为毫秒*/ in_keep_alive.keepalivetime = 1000; /*多长时间没有报文开始发送keepalive心跳包-单位为毫秒*/ ret = WSAIoctl(socket, SIO_KEEPALIVE_VALS, (LPVOID)&in_keep_alive, ul_in_len, (LPVOID)&out_keep_alive, ul_out_len, &ul_bytes_return, NULL, NULL); if (ret == SOCKET_ERROR) { printf("WSAIoctl failed: %d \n", WSAGetLastError()); return -1; } return 0;
}

以TCP 客户端为例:

SHORT CClientCtrl::connetServer(LPCTSTR strAddr,USHORT portNum)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState()); // TODO: Add your dispatch handler code here
m_addr = strAddr;
USES_CONVERSION;
char *pCharAddr = T2A(m_addr); WSADATA wsd;
WSAStartup(MAKEWORD(2, 2), &wsd);
m_sockClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
SOCKADDR_IN ClientAddr; ClientAddr.sin_family = AF_INET;
ClientAddr.sin_addr.S_un.S_addr = inet_addr(pCharAddr);//
ClientAddr.sin_port = htons(portNum);//m_port
int n = 0;
n = connect(m_sockClient, (struct sockaddr*)&ClientAddr, sizeof(ClientAddr));
if (n == SOCKET_ERROR) { return -1;
} //set keepAlive
n = socket_tcp_alive(m_sockClient);//设置keepalive
if (n <0 )
{
return -1;
} CreateThread(NULL, 0, &recvFromServer, (LPVOID)this, 0, NULL); return 0;
}
DWORD WINAPI  recvFromServer(LPVOID lpParameter)
{
char RecvBuf[MaxBufSize];
CClientCtrl* pParent = (CClientCtrl*)lpParameter;
SOCKET *ClientSocket = &(pParent->m_sockClient);
int iLength;
while (true) {
memset(RecvBuf, '\0', sizeof(RecvBuf));
iLength = recv(*ClientSocket, RecvBuf, MaxBufSize, 0);
if (iLength <=0) //error
{ strcpy(RecvBuf,"ERROR");
::SendMessage(pParent->m_hWnd,WM_RECVMSG,(WPARAM)RecvBuf,0); break;
}
else
{
::SendMessage(pParent->m_hWnd,WM_RECVMSG,(WPARAM)RecvBuf,0); } }
return 0;
}

recv函数的返回值能反应网络的状态;

iLength = recv(*ClientSocket, RecvBuf, MaxBufSize, 0);

如果服务器端正常关闭socket ,那么recv 的返回值iLength 为0;这种情况即使不设置keepAlive 也是可以正常返回的;

如果出现暴力关闭,比如网线被拔,服务器程序强行关闭,recv 的返回值iLength 为-1; 如果不设置keepAlive 的话,这里是不会有任何反应的。

参考文献:http://blog.csdn.net/embedded_sky/article/details/42077321

Windows 下TCP长连接保持连接状态TCP keepalive设置的更多相关文章

  1. CentOS下安装MySQL,Windows下使用Navicat for MySql连接

    安装 查看有没有安装过:          yum list installed mysql*          rpm -qa | grep mysql* 查看有没有安装包:          yu ...

  2. windows下使用vnc viewer远程连接Linux桌面(转)

    在windows下使用vnc viewer远程连接Linux桌面,主要配置步骤: Linux: 1.rpm -qa vnc //查看是否安装vnc服务,如果没有安装,可以使用yum,或者rpm进行安装 ...

  3. Windows下对postgre开启远程连接权限

    编辑 删除 前言:Windows下对postgre开启远程连接权限,下面是实际操作过程中的手顺 1.找到postgresql.conf文件,注意安装路径 D:\Program Files (x86)\ ...

  4. windows下安装oracle,sqlplus连接启动oracle(oracle 主机字符串输入是什么)

    1.oracle安装 参考http://wenku.baidu.com/view/d01ffd43336c1eb91a375d68.html,这里不再赘述 2.命令行sqlplus连接oracle   ...

  5. windows下git库的ssh连接,使用public key的方法

    在windows下进行项目开发,使用git,通过ssh方式与git库连接,而ssh方式用public key实现连接. 首先需要下载mygit,安装后使用git bash.git bash(有GUI界 ...

  6. windows下通过navicat for mysql连接centos6.3-64bit下的MySQL数据库

    一.centos下MySQL安装 按照命令依次安装以下文件: mysql-devel 开发用到的库以及包含文件 mysql mysql 客户端 mysql-server 数据库服务器 yum inst ...

  7. 桌面版centos安装vncserver并在windows下使用VNC Viewer远程连接

    首先关闭防火墙 在Centos中安装vncserver yum install tigervnc-server 拷贝一份  /lib/systemd/system/vncserver@.service ...

  8. windows下使用VNC进行远程连接

    在 windows 电脑上安装 VNC,包含 VNC server 和 VNC viewer,如果仅需要被操控或操控他人,选择型下载安装 VNC server 或 VNC viewer 即可. 在需要 ...

  9. windows下在eclipse上远程连接hadoop集群调试mapreduce错误记录

    第一次跑mapreduce,记录遇到的几个问题,hadoop集群是CDH版本的,但我windows本地的jar包是直接用hadoop2.6.0的版本,并没有特意找CDH版本的 1.Exception ...

  10. windows下Apache配置SSL安全连接

    什么是SSL? SSL(Secure Socket Layer): 是为Http传输提供安全的协议,通过证书认证来确保客户端和网站服务器之间的数据是安全.Open SSL下载地址:http://www ...

随机推荐

  1. varchar(1)占用几个字节

    在version4之前,MySQL中varchar长度是按字节:而version5之后,按字符.如varchar(6),在version4,表示占用6个字节,而在version5中,表示占用6个字符. ...

  2. C#定时任务(Timer)

    新建Timer类 using BaseAsset.Data.Infrastructure; using BaseAsset.Data.Repositories; using BaseAsset.Ent ...

  3. CentOS 7.9 环境下部署 Docker 服务

    sudo setenforce Permissive sudo vi /etc/selinux/config SELINUX=permissive sudo systemctl stop firewa ...

  4. 书剑恩仇录<随笔>感想

    书剑恩仇录是去年读完的,剧情上的细节处已经遗忘甚多,但本书也金庸先生的第一篇长篇武侠小说.此书的重要性不言而喻 摘要:故事的开头源于武当派陆菲青.因犯了杀人官司隐姓埋名为李沅芷的教书先生.因仇家寻上门 ...

  5. java循环中的break和continue的小笔记

    代码1: for(int i=0;i<10;i++){ System.out.println(i); continue; System.out.println("flag") ...

  6. Error running 'tm8': Cannot load C:\Users\Administrator\.IntelliJIdea2019.3\system\tomcat\Unnamed_jymes_3\conf\server.xml (系统找不到指定的文件。)

    救命救命,由于脑壳被门夹了去更改了idea的配置,导致重启项目报错!又是给自己挖坑的一天,唉!!! 主要是看报错信息还一直以为是tomcat的问题,然后试了很多方法,比如查看配置的tomcat路径.重 ...

  7. c++11 智能指针学习汇总

    c++为什么要引入智能指针? C/C++ 语言最为人所诟病的特性之一就是存在内存泄露问题,因此后来的大多数语言都提供了内置内存分配与释放功能,有的甚至干脆对语言的使用者屏蔽了内存指针这一概念.这里不置 ...

  8. react常见bug - 查询条件变化,但page未重置为1

    问题1.多次触发请求,且存在潜在的竞态问题 const [page, setPage] = useState(1); const [keyword, setKeyword] = useState('' ...

  9. AI基本知识

    一.什么是flops 对flops有疑惑,首先得先捋清这个概念: FLOPS:注意全大写,是floating point operations per second的缩写,意指每秒浮点运算次数,理解为 ...

  10. MyBatis面试题汇总

    1.什么是Mybatis? Mybatis是对象关系映射一个框架,它内部封装了JDBC,开发的时候只要关注SQL语句本身,可以严格控制sql的执行性能,灵活,其二可以通过XML或者注解来配置映射信息 ...