http://www.cnblogs.com/caosiyang/archive/2012/03/29/2422956.html

Linux下tcp连接断开的时候调用close()函数,有优雅断开和强制断开两种方式。

那么如何设置断开连接的方式呢?是通过设置socket描述符一个linger结构体属性。

linger结构体数据结构如下:

#include <arpa/inet.h>struct linger {
  int l_onoff;
  int l_linger;
};

三种断开方式:

1. l_onoff = 0; l_linger忽略

close()立刻返回,底层会将未发送完的数据发送完成后再释放资源,即优雅退出。

2. l_onoff != 0; l_linger = 0;

close()立刻返回,但不会发送未发送完成的数据,而是通过一个REST包强制的关闭socket描述符,即强制退出。

3. l_onoff != 0; l_linger > 0;

close()不会立刻返回,内核会延迟一段时间,这个时间就由l_linger的值来决定。如果超时时间到达之前,发送完未发送的数据(包括FIN包)并得到另一端的确认,close()会返回正确,socket描述符优雅性退出。否则,close()会直接返回错误值,未发送数据丢失,socket描述符被强制性退出。需要注意的时,如果socket描述符被设置为非堵塞型,则close()会直接返回值。

具体用法:

struct linger ling = {0, 0};
setsockopt(socketfd, SOL_SOCKET, SO_LINGER, (void*)&ling, sizeof(ling));

http://blog.csdn.net/yunhua_lee/article/details/8146837

其取值和处理如下:
1、设置 l_onoff为0,则该选项关闭,l_linger的值被忽略,等于内核缺省情况,close调用会立即返回给调用者,如果可能将会传输任何未发送的数据;
2、设置 l_onoff为非0,l_linger为0,则套接口关闭时TCP夭折连接,TCP将丢弃保留在套接口发送缓冲区中的任何数据并发送一个RST给对方,
   而不是通常的四分组终止序列,这避免了TIME_WAIT状态;
3、设置 l_onoff 为非0,l_linger为非0,当套接口关闭时内核将拖延一段时间(由l_linger决定)。
   如果套接口缓冲区中仍残留数据,进程将处于睡眠状态,直 到(a)所有数据发送完且被对方确认,之后进行正常的终止序列(描述字访问计数为0)
   或(b)延迟时间到。此种情况下,应用程序检查close的返回值是非常重要的,如果在数据发送完并被确认前时间到,close将返回EWOULDBLOCK错误且套接口发送缓冲区中的任何数据都丢失。
   close的成功返回仅告诉我们发送的数据(和FIN)已由对方TCP确认,它并不能告诉我们对方应用进程是否已读了数据。如果套接口设为非阻塞的,它将不等待close完成。
   
第一种情况其实和不设置没有区别,第二种情况可以用于避免TIME_WAIT状态,但在Linux上测试的时候,并未发现发送了RST选项,而是正常进行了四步关闭流程,
初步推断是“只有在丢弃数据的时候才发送RST”,如果没有丢弃数据,则走正常的关闭流程。
查看Linux源码,确实有这么一段注释和源码:
=====linux-2.6.37 net/ipv4/tcp.c 1915=====
/* As outlined in RFC 2525, section 2.17, we send a RST here because
* data was lost. To witness the awful effects of the old behavior of
* always doing a FIN, run an older 2.1.x kernel or 2.0.x, start a bulk
* GET in an FTP client, suspend the process, wait for the client to
* advertise a zero window, then kill -9 the FTP client, wheee...
* Note: timeout is always zero in such a case.
*/
if (data_was_unread) {
/* Unread data was tossed, zap the connection. */
NET_INC_STATS_USER(sock_net(sk), LINUX_MIB_TCPABORTONCLOSE);
tcp_set_state(sk, TCP_CLOSE);
tcp_send_active_reset(sk, sk->sk_allocation);

另外,从原理上来说,这个选项有一定的危险性,可能导致丢数据,使用的时候要小心一些,但我们在实测libmemcached的过程中,没有发现此类现象,
应该是和libmemcached的通讯协议设置有关,也可能是我们的压力不够大,不会出现这种情况。

第三种情况其实就是第一种和第二种的折中处理,且当socket为非阻塞的场景下是没有作用的。
对于应对短连接导致的大量TIME_WAIT连接问题,个人认为第二种处理是最优的选择,libmemcached就是采用这种方式,
从实测情况来看,打开这个选项后,TIME_WAIT连接数为0,且不受网络组网(例如是否虚拟机等)的影响

struct linger 用法相关推荐

  1. struct linger

    Linux下tcp连接断开的时候调用close()函数,有优雅断开和强制断开两种方式. 那么如何设置断开连接的方式呢?是通过设置socket描述符一个linger结构体属性. linger结构体数据结 ...

  2. struct linger

    TCP连接断开的时候调用close socket函数,已经讨论过有优雅的断开和强制断开,那么如何设置断开连接的方式呢? 是通过设置socket描述符一个linger结构体属性. linger结构体数据 ...

  3. C语言struct 函数,c语言struct的用法

    C语言中先申明结构体,也就是定义结构体具体形式,而后可以把它当做普通数据类型来修饰变量,也可以在定义类型时后面直接跟着定义几个变量,下面小编就为你介绍c语言struct的用法. 基本定义:结构体,通俗 ...

  4. struct sysinfo 用法

    在Linux中,sysinfo是用来获取系统相关信息的结构体,其原型如下: struct sysinfo {     long uptime;                   /* Seconds ...

  5. struct timeval用法与时间溢出问题

    1.用法 高精度计算时间的结构体struct timeval. 头文件是sys/time.h 网上查找的定义是 #include "sys/time.h"struct timeva ...

  6. matlab中struct2,Matlab中struct的用法

    struct在matlab中是用来建立结构体数组的.通常有两种用法: s = struct('field1',{},'field2',{},...) 这是建立一个空的结构体,field1,field2 ...

  7. linux sysinfo结构体,struct sysinfo 用法

    在Linux中,sysinfo是用来获取系统相关信息的结构体,其原型如下: struct sysinfo { long uptime;                   /* Seconds sin ...

  8. Linux struct itimerval用法

    先看一段代码 #include <stdio.h> #include <time.h> #include <sys/time.h> #include <std ...

  9. C++中struct的用法

    废话 struct是个很有用的东西呢! 进入正题 struct的用处是定义一个新的类型,而这个类型里面可以是各种各样的东西. 比如: struct node{//定义一个新的类型叫nodeint a; ...

最新文章

  1. 曝光原理_PS教程:双重曝光的原理及制作过程,魔术棒及调整边缘的简易抠图...
  2. templates的语法
  3. 微软职位内部推荐-SW Engineer II for WinCE
  4. 甲骨文宣布供应链管理云平台支持LogFire仓库管理系统
  5. linux 递归创建线程,[linux]二叉树的建立及其递归遍历(C语言实现)
  6. 使用markdown编辑器(自用,没内容。。)
  7. 消息中间件学习总结(19)——生产案例:消息中间件 MQ 如何处理消费失败的消息?
  8. ExtJS4.2学习(七)EditorGrid可编辑表格(转)
  9. chkconfig用法
  10. 计算机组成原理----Cache主存地址映射(计算题)
  11. 回文数 LeetCode
  12. centos7 搭建安装zabbix3.0邮件告警实例(二)
  13. Android webm转mp4,android - 如何记录屏幕并输出视频格式为webm并由vp9编码? - 堆栈内存溢出...
  14. 存储过程与自定义函数的区别
  15. VBA按行读取TXT文本文件
  16. 手机查看IGES,STP,STEP文件APP推荐-Glovius
  17. java 服务器调优_Java远程服务器调优
  18. 程序员 -- 当我彻底放弃自私自利后,前途变得一片光明,不能过多的只是关注自己的功夫,生活不能只局限在方寸虚拟世界里
  19. word中,去表格格式,把表格转换为文本的方法
  20. html打开方式解锁,解锁bootloader

热门文章

  1. Apache配置虚拟主机的三种方法
  2. Android进程间通信 Messenger详解
  3. 计算机仿真如何汇款,【计算机仿真杂志社】计算机仿真杂志社编辑部
  4. input金额失焦自动补零和千分位格式化
  5. SLAM让你如何去理解这个世界
  6. Paddle Inference和Paddle Serving
  7. Azkaban概述详解
  8. Java模拟Http请求远程接口
  9. python seo 相关的库_【张亚楠】Python你必须知道的十个库【翻】
  10. SSL P1618 剑鱼行动