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. -bash: ./mlnxofedinstall: /usr/bin/perl: bad interpreter: No such file or directory

    -bash: ./mlnxofedinstall: /usr/bin/perl: bad interpreter: No such file or directory 解决办法:安装相关的环境即可 输 ...

  2. ElementUI实现手动上传

    在做项目中,与同事遇到问题,顺手记录一下 <template> <div class="common-layout"> <el-button size ...

  3. TypeScript 元组

    TypeScript 元组 我们知道数组中元素的数据类型都一般是相同的(any[] 类型的数组可以不同),如果存储的元素数据类型不同,则需要使用元组. 元组中允许存储不同类型的元素,元组可以作为参数传 ...

  4. java-正确打日志

    使用 slf4j 使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一. 实现方式统一使用: Logback 框架 打日志的正确方式 什么时候应该打日志 当你遇到问题的时候,只能通过 debu ...

  5. 搭建python+appium环境的时候遇到 'could not find adb.exe!'的问题

    搭建Android环境的时候遇到 'could not find adb.exe!'的问题 如果是在的C:\android-sdk-windows\tools目录下并没有adb.exe这个可执行文件. ...

  6. 解决tomcat8080端口占用问题

    解决tomcat8080端口占用问题 1. 使用管理员权限打开cmd 2. 输入 netstat -ano | findstr 8080 找出占用8080端口的进程pid netstat -ano | ...

  7. vue后台管理系统——权限管理模块

    电商后台管理系统的功能--权限管理模块 1. 权限管理业务分析 通过权限管理模块控制不同的用户可以进行哪些操作,具体可以通过角色的方式进行控制,即每个用户分配一个特定的角色,角色包括不同的功能权限. ...

  8. linux分区增加硬盘空间

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

  9. Array of products

    refer to: https://www.algoexpert.io/questions/Array%20Of%20Products Problem Statement Sample input A ...

  10. 基础篇二:Linux常用系统命令

    Linux常用系统命令 pwd 打印当前目录 cd /目录 切换目录 cd ..   切换上一级目录 ls 显示目录 ls -a  包括隐藏文件 ls -l 以长格式列出 alias 当前系统所有别名 ...