免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6828 | 回复: 8

[函数] 困惑:socket通信使用阻塞模式,一旦对端进程崩溃或关闭连接,recv不能马上返回值吗? [复制链接]

论坛徽章:
0
发表于 2013-11-01 11:24 |显示全部楼层
以下实验在windows下作,

      实验一:网上有种说法:“阻塞模式下直接使用套接字接收或者发送,如果通信的对端关闭连接或者对端进程崩溃,则这边的recv函数就会长时间不返回值
”,但是我实际编了个程序测试了阻塞模式下的recv,发现在对端关闭连接就马上返回0,如果对端进程崩溃,则recv马上返回  < 0; 而且都是立即就能返回,
     实验二:拔网线断网,如果建立的长连接,分拨的是自己机子的网线还是拔得是对端的网线两种情况,仅仅把自己的机子网线拔掉,自己机子的recv需要几秒钟能返回,无论是select模式还是阻塞模式都是如此, 仅仅拔掉远端机子的网线,本机这端的网线不动,则本机的recv套接子,无论是select还是阻塞模式,都无法感知远端网线是否拔掉,拔对端的网线,得靠对端自己的recv,能在几秒钟后感知,本地机子不可能感知远端的网线拔掉,这个和远端程序崩溃不一样,远端程序崩溃,本地机子recv马上就能返回,无论是select还是阻塞模式,我做实验得出的结论

我的结论: 1 我觉得所谓”阻塞模式下直接使用套接字接收,一旦通信对方关闭或者进程崩溃,不能马上返回对端这些异常,只有selcet模式可以马上返回异常,“这说法是错误的!两者都可以 马上返回值,但两种方式都不能感受到远端的网线是否拔掉,两者都可以在自己机子的网线拔掉后几秒钟感知到
           结论2 :一个套接字情况下,select模式和直接阻塞模式使用套接字相比,优势只体现在select是异步模式,可以发,收分开,而直接阻塞模式,如果要一问一答,则只能同步,即:发完后等到对方应答后才能再发。对“马上感知对端通信异常(指对端套接字关闭,对端进程崩溃)”而言, 两者效果一样!(当然,如果通信双方使用>=2个的套接子通信,select还是比仅仅使用两个都阻塞模式的套接字的优势多了起来,不再赘述)

请高人指教,我上述两点是否正确?多谢!

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2013-11-01 12:29 |显示全部楼层
这跟是否阻塞一点关系都没有。 程序崩溃,操作系统会负责发送Rst包的,另一端是能够立刻感知的。 中间网络设备断掉是没有感知的,TCP层是靠KEEP_ALIVE包检查连接状态,linux上默认是两小时发送一次。应用层自己加心跳。

论坛徽章:
0
发表于 2013-11-01 12:56 |显示全部楼层
本帖最后由 hisense0709 于 2013-11-01 12:56 编辑

楼上高人多谢指点!!!但你说的“中间网络设备断掉是没有感知的,”, 但是我发现“把自己的机子网线拔掉,自己机子的recv只要几秒钟感知到能返回,无论是select模式还是阻塞模式都是如此,”, 自己的机子的网线,似乎应该是中间网络设备呀,所以,你说的是否不严谨?

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
发表于 2013-11-01 13:06 |显示全部楼层
网络环境复杂, TCP协议只是两个端自己维护的一个状态, 如果不去验证链路是否通常, 那么网线拔了之类的肯定是不知道的.

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
发表于 2013-11-01 13:44 |显示全部楼层
>> 本地机子recv马上就能返回,无论是select还是阻塞模式,
<< 这个要看对方的实现, 一般OS会给程序做收尾工作。

>> 但是我发现“把自己的机子网线拔掉,自己机子的recv只要几秒钟感知到能返回
<< 本机能够很快检测到自已网络不通, 但远端因为网络状况不同, 无法预测廷迟时间, 只能等最大超时。

论坛徽章:
17
处女座
日期:2013-08-27 09:59:352015亚冠之柏太阳神
日期:2015-07-30 10:16:402015亚冠之萨济拖拉机
日期:2015-07-29 18:58:182015年亚洲杯之巴勒斯坦
日期:2015-03-06 17:38:17摩羯座
日期:2014-12-11 21:31:34戌狗
日期:2014-07-20 20:57:32子鼠
日期:2014-05-15 16:25:21亥猪
日期:2014-02-11 17:32:05丑牛
日期:2014-01-20 15:45:51丑牛
日期:2013-10-22 11:12:56双子座
日期:2013-10-18 16:28:17白羊座
日期:2013-10-18 10:50:45
发表于 2013-11-01 14:21 |显示全部楼层
回复 3# hisense0709


    他说的情况比较有代表性的是路由环节,尤其是公网的路由,当某个节点路出现问题时路由器会自己切换到其它路由上,此时通信的双方并不知道某个节点路由出了问题,你拔掉网线只能说明通信的端点上出现问题。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2013-11-01 16:52 |显示全部楼层
回复 3# hisense0709


    应该是操作系统感知,然后通知进程了。

论坛徽章:
0
发表于 2013-11-01 17:07 |显示全部楼层
本帖最后由 c/unix 于 2013-11-01 17:08 编辑

如果是阻塞的recv,也没有设置心跳包,
对方close,或者进程奔溃,是可以返回的<=0
类似直接拔网线这种,是不会返回的,楼主测试的时候不要用虚拟机测试。

论坛徽章:
7
摩羯座
日期:2013-12-05 10:42:57辰龙
日期:2013-12-27 13:40:49亥猪
日期:2014-01-15 09:10:37天秤座
日期:2014-01-20 11:22:20辰龙
日期:2014-01-26 17:02:25午马
日期:2014-01-27 14:22:34水瓶座
日期:2014-02-19 09:36:40
发表于 2013-11-01 21:08 |显示全部楼层
@linux_c_py_php仁兄是不是开发游戏的,石器的代码如何看才能入手,请指教
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

SACC2019中国系统架构师大会

【数字转型 架构演进】SACC2019中国系统架构师大会
2019年10月31日~11月2日第11届中国系统架构师大会(SACC2019)将在北京隆重召开。四大主线并行的演讲模式,1个主会场、20个技术专场、超千人参与的会议规模,100+来自互联网、金融、制造业、电商等领域的嘉宾阵容,将为广大参会者提供一场最具价值的技术交流盛会。




----------------------------------------

大会官网>>
  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP