免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3956 | 回复: 8
打印 上一主题 下一主题

[C] 【没人回答也继续问,struct linger与fcntl的较量】 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-09-23 11:24 |只看该作者 |倒序浏览
struct linger
{
     int l_onoff;
     int l_linger;
};
有三种组合方式:
第一种
    l_onoff = 0;
    l_linger忽略
    这种方式下,就是在closesocket的时候立刻返回,底层会将未发送完的数据发送完成后再释放资源,也就
是优雅的退出。
第二种
    l_onoff非零
    l_linger = 0;
    这种方式下,在调用closesocket的时候同样会立刻返回,但不会发送未发送完成的数据,而是通过一个REST包强制的关闭socket描述符,也就是强制的退出。
第三种
    l_onoff非零
    l_linger > 0

    这种方式下,在调用closesocket的时候不会立刻返回,内核会延迟一段时间,这个时间就由l_linger得值来决定。
    如果超时时间到达之前,发送完未发送的数据(包括FIN包)并得到另一端的确认,closesocket会返回正确,socket描述符优雅性退出。
    否则,closesocket会直接返回错误值,未发送数据丢失,socket描述符被强制性退出。
   
   
假设有一socket,现作如下操作将socket设置为非阻塞)
Flag=fcntl(sock,F_GETFL,0);
Flag=fcntl(sock,F_SETFL,Flag|O_NONBLOCK);

问题:这种操作相当于上面三种方式的哪一种?或者哪一种都不是,如果是这样,那另一问题是,我既采用linger第三种方式
又通过fcntl设置成O_NONBLOCK,程序会如何处理(这样很矛盾啊,反正程序应该不会这么写吧)?

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
2 [报告]
发表于 2011-09-23 11:31 |只看该作者
关注一下, 一直潜意识的认为 O_NONBLOCK 和 read/write 相关; 还真没有想过有没有影响到 close

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
3 [报告]
发表于 2011-09-23 11:32 |只看该作者
直觉应该是不影响 close 吧

论坛徽章:
0
4 [报告]
发表于 2011-09-23 11:42 |只看该作者
直觉应该是不影响 close 吧
zylthinking 发表于 2011-09-23 11:32



    我不清楚才问的,而且我看到一种解释:【需要注意的时,如果socket描述符被设置为非堵塞型,则closesocket会直接返回值。】
我拿了两个平台的代码看了下,有struct linger设置的绝对没出现fcntl(LsnSock,F_SETFL,Flag|O_NONBLOCK)这种操作,
相对的,有fcntl操作的也不会出现stuct linger,所以就产生疑惑了

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
5 [报告]
发表于 2011-09-23 11:44 |只看该作者
我也看到你所说的文章了, 是不是这个?

setsockopt的调用将依上面结构的两个值产生三种情况的某一种
1。如果l_onoff是0,选项被关闭。l_linger的值被忽略且前面讨论的TCP缺省设置生效,close立即返回。
2。如果l_onoff非0,且l_linger为0,那么当套接口关闭时TCP夭折连接。TCP将丢弃保留的套接口发送缓冲区的任何数据并发送一个 RST给对方,而不是通常的四分组连接终止序列。这避免了TCP的TIME_WAIT状态,但这样做也会有以下可能性。但这样做也会有以下可能性:在 2MSL妙内创建此连接的令一个化身,并使得老的来自刚被终止的连接上的重复分节不正确地传递到新的化身上。
     有些实现,尤其是solaris。不实现SO_LINGER选项的这个特性。TIME_WAIT状态是我们的朋友,它是有助于我们的(也就是说,使旧的重复分节在网络中超时消失)。不要试图避免这个状态。
3,如果l_onoff和l_linger都为非0。那么当套接口关闭时内核将拖延一段时间。也就是说,如果在发送缓冲区中仍有数据。进程将处于睡眠状 态,一直到(a)所有数据都已发送完且均被对方确认或(b)延滞时间到。如果套接口被设置为非阻塞型。它将不等待close完成,即使延滞时间为非0也是 如此。当使用SO_LINGER选项的这个特性时,应用进程检查close的返回值是非常重要的,因为,如果在数据发送完并被确认前延滞时间到的话, close将返回EWOULDBLOCK 错误且套接口发送缓冲区中的任何数据都丢失。
      第三种情况中对成员l_linger非0的解释是依赖不同的实现的。4.4BSD假设其单位是时钟滴答(一百分之一秒),但posix.1g规定其单位为 秒。现有的源自Berkeley的实现的另一个问题是成员l_linger(一个整数)是拷贝到16位的带符号整数内核变量so_linger上的,这就 限制了延滞时间最大为32767时钟滴答即327.67秒。
在HTTP应用中,存在一个问题,SERVER由于某种原因关闭连接,如KEEPALIVE的超时,这样,作为主动关闭的SERVER一方就会进入 FIN_WAIT2状态,但TCP/IP协议栈有个问题,FIN_WAIT2状态是没有超时的(不象TIME_WAIT状态),所以如果CLIENT不关 闭,这个FIN_WAIT_2状态将保持到系统重新启动,越来越多的FIN_WAIT_2状态会致使内核crash

chdonald 回复于:2003-07-11 12:30:51
产生原因:
1。常连接并且当连接一直处于IDLE状态导致SERVER CLOSE时,CLIENT编程缺陷,没有向SERVER 发出FIN和ACK包
2。APACHE1.1和APACHE1.2增加了linger_close()函数,前面的帖子有介绍,这个函数可能引起了这个问题(为什么我也不清楚)

解决办法:
1。对FIN_WAIT_2状态增加超时机制,这个特性在协议里没有体现,但在一些OS中已经实现
如:LINUX、SOLARIS、FREEBSD、HP-UNIX、IRIX等
2。不要用linger_close()编译
3。用SO_LINGER代替,这个在某些系统中还能很好地处理
4。增加用于存储网络连接状态的内存mbuf,以防止内核crash
5。DISABLE KEEPALIVE

论坛徽章:
0
6 [报告]
发表于 2011-09-23 11:48 |只看该作者
我也看到你所说的文章了, 是不是这个?

setsockopt的调用将依上面结构的两个值产生三种情况的某一种
1 ...
zylthinking 发表于 2011-09-23 11:44



    好像不是这个,我只是摘了一些我需要的东西,原文我没找到~~~呵呵

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
7 [报告]
发表于 2011-09-23 11:50 |只看该作者
我现在琢磨着是不是这么回事, O_NONEBLOCK 被设置, close 如果发现尚有数据未发送, 则无条件返回 EWOULDBLOCK; 但协议栈保留数据, 并尝试在 linger 时间内发送, 如果未完成而时间到, 则忽略余下的数据;   无论是不是EWOULDBLOCKfd 应该在close 返回前就被销毁了, 协议栈保留下的是 files 结构足够了

论坛徽章:
0
8 [报告]
发表于 2011-09-23 13:21 |只看该作者
设置了linger非0时间,再非阻塞套接字是不推荐使用的
close会返回wouldblock,需要再次关闭

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
9 [报告]
发表于 2011-09-23 14:05 |只看该作者
设置了linger非0时间,再非阻塞套接字是不推荐使用的
close会返回wouldblock,需要再次关闭
pself 发表于 2011-09-23 13:21


那关闭时机呢, 不会自己做计时器吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP