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. Oracle修改用户密码错误次数及解锁用户

    ORACLE11g错误密码登录默认是10次,10次错误后用户将被锁定,如下: SQL> conn test/123456 ERROR: ORA-28000: the account is loc ...

  2. vue保持滚动条在底部

    mounted() { this.scrollToBottom(); }, updated: function () { this.scrollToBottom(); }, scrollToBotto ...

  3. 记一次p标签内容不换行记录

    p标签内容l里面如果全部是英文,那么默认是不会换行的. 需要添加word-wrap: break-word; 属性 这样就会自动换行了

  4. flask、element、vue项目实战:搭建一个加密excel数据的网站

    文章目录 一.前端 1.1 上传文件 1.2 数据表格 1.3 加密选项 1.4 加密数据 1.5 下载按钮 二.后端 2.1 .upload 文件上传 2.2 table 数据表格接口 2.3 en ...

  5. 模态框拖拽案例分析--元素偏移量 offset 系列

    弹出框,我们也称为模态框. 模态框拖拽案例分析: (1)点击弹出层, 会弹出模态框, 并且显示灰色半透明的遮挡层. (2)点击关闭按钮,可以关闭模态框,并且同时关闭灰色半透明遮挡层. (3)鼠标放到模 ...

  6. UE4_C++笔记

    目录 C++ 获取当前世界指针 创建文件夹拾取窗口 获取Actor所在地图名称 选择世界里所有指定类型的Actor 获取当前世界所有已加载关卡 获取当前选择的已加载关卡 获取关卡名称 判断文件/路径是 ...

  7. arthas jad 反编译 xxx类 ,报 No class found for:xxx

    可能的原因: 类名不对,需要用全限定名,并且注意区分大小写 根据官方的文档,arthas jad 只能反编译已经加载的类.

  8. Django基础篇 06-Django模板过滤器Filter和标签Tags

    一.Django模板的内置过滤器Filter 什么是模板(Template)? Django的Template是如何工作的 Django的模板是静态的html文件,它只决定了一个页面的样式或外观.它需 ...

  9. 解决LayUI中的 laydate 点击一闪而过问题

    加一个:trigger: 'click' <input name="apbegin" id="apbegin" class="layui-inp ...

  10. 修改tomcat启动时,修改默认访问的页面