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. Alfred 好用工具分享

    好用的mac工具分享 1.带历史记录的剪切板 根据快捷键切换选择保存的数据 2.创建热键工作流程 将常用的工具变为热键,快捷切换 如何创建: 设置热键 单击右键 创建actions 打开app 然后将 ...

  2. 使用Wireshark完成实验2-TCP

    1.打开Google Chorme,进入https://gaia.cs.umass.edu/wireshark-labs/alice.txt 2.将文本保存,进入https://gaia.cs.uma ...

  3. 在Unity3D中开发的Dissolve Shader

    Swordmaster Dissolve Shaders 特点 本插件共包含两种Dissolve Shader: (1).一种类型是Bumped Specular工作流的Dissolve Shader ...

  4. FFT简单概述

    概念 快速傅里叶变换 (fast Fourier transform), 即利用计算机计算离散傅里叶变换(DFT)的高效.快速计算方法的统称,简称FFT.快速傅里叶变换是1965年由J.W.库利和T. ...

  5. 一次讲清promise

    此文章主要讲解核心思想和基本用法,想要了解更多细节全面的使用方式,请阅读官方API 这篇文章假定你具备最基本的异步编程知识,例如知道什么是回调,知道什么是链式调用,同时具备最基本的单词量,例如page ...

  6. 等级保护2.0 三级-Linux 测评指导书

    等级保护2.0 三级-Linux 测评指导书 1.1安全计算环境 1.1.1身份鉴别        1.1.2访问控制        1.1.4入侵防范       1.1.5恶意代码防范      ...

  7. jquery 判断字符串长度

    function titleLength(str) { var strLength = 0; var list = str.split(""); for (var i = 0; i ...

  8. linux分区增加硬盘空间

    https://blog.csdn.net/netgc/article/details/119978449

  9. PHP、Navicat安装

    一.PHPStudy小皮面板:https://public.xp.cn/upgrades/phpStudy_64.zip 下载完成后解压后双击 点击立即安装 安装完成 启动MySQL,Nginx(my ...

  10. 【编程】Python3 使用自定义编码字符表解密Base64数据

    前言 Python提供了"base64"模块用于编码.解码Base64数据.但是并不是所有的Base64数据都会使用默认的字符表进行编码,所以这里对Python下实现自定义编码字符 ...