9.tcp设置超时检测和检测网线是否断开

使用在客户端中




//设置超时时间
struct timeval timeout = { 5, 0};
err = setsockopt( this-> sock_client,SOL_SOCKET, SO_SNDTIMEO,( const char*)&timeout, sizeof(timeout));
if(err != 0x00){ return - 1;}
err = setsockopt( this-> sock_client,SOL_SOCKET, SO_RCVTIMEO,( const char*)&timeout, sizeof(timeout));
if(err != 0x00){ return - 1;}
//检测网线是否断开
int keepalive = 1; // 开启keepalive属性
int keepidle = 10; // 如该连接在10秒内没有任何数据往来,则进行探测
int keepinterval = 3; // 探测时发包的时间间隔为3 秒
int keepcount = 3; // 探测尝试的次数.如果第1次探测包就收到响应了,则后2次的不再发.
setsockopt( this-> sock_client, SOL_SOCKET, SO_KEEPALIVE, ( void *)&keepalive , sizeof(keepalive ));
setsockopt( this-> sock_client, SOL_TCP, TCP_KEEPIDLE, ( void*)&keepidle , sizeof(keepidle ));
setsockopt( this-> sock_client, SOL_TCP, TCP_KEEPINTVL, ( void *)&keepinterval , sizeof(keepinterval ));
setsockopt( this-> sock_client, SOL_TCP, TCP_KEEPCNT, ( void *)&keepcount , sizeof(keepcount ));

相关说明:

TCP keepAlive含义:

在TCP中有一个Keep-alive的机制可以检测死连接,原理很简单,TCP会在空闲了一定时间后发送数据给对方:

1.如果主机可达,对方就会响应ACK应答,就认为是存活的。
2.如果可达,但应用程序退出,对方就发RST应答,发送TCP撤消连接。
3.如果可达,但应用程序崩溃,对方就发FIN消息。

4.如果对方主机不响应ack, rst,继续发送直到超时,就撤消连接。这个时间就是默认的二个小时。


在一个正常的TCP连接上,当我们用无限等待的方式调用下面的Recv或Send的时候:

   ret=recv(s,&buf[idx],nLeft,flags);

   或

   ret=send(s,&buf[idx],nLeft,flags);

   如果TCP连接被对方正常关闭,也就是说,对方是正确地调用了closesocket(s)或者shutdown(s)的话,那么上面的Recv或Send调用就能马上返回,并且报错。这是由于closesocket(s)或者shutdown(s)有个正常的关闭过程,会告诉对方“TCP连接已经关闭,你不需要再发送或者接受消息了”。但是,如果是网线突然被拔掉,TCP连接的任何一端的机器突然断电或重启动,那么这时候正在执行Recv或Send操作的一方就会因为没有任何连接中断的通知而一直等待下去,也就是会被长时间卡住。这种情形解决的办法是启动TCP编程里的keepAlive机制。


你可能感兴趣的:(网络编程)