免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: yulc
打印 上一主题 下一主题

linux下非阻塞的tcp研究 [复制链接]

论坛徽章:
0
61 [报告]
发表于 2007-07-31 15:23 |只看该作者
原帖由 醉卧水云间 于 2007-7-31 14:53 发表


我记得win下可以设置缓冲为0,不过也不敢肯定,还真没这么设置过,能不能设置为0和系统实现有关,逻辑上没有一点问题,没有缓冲你就直接发应用程序里的数据嘛。如果linux不允许0缓冲,那可能是没考虑给用户 ...

在windows不知道,linux2.4中可以设0,不过被内核修正了传进去的值。
val * 2 < SOCK_MIN_BUF。send buff 就设成SOCK_MIN_BUF.

论坛徽章:
0
62 [报告]
发表于 2007-07-31 15:41 |只看该作者
我是比较同意flw的看法,在我看来,send、recv就是与缓冲区打交道,跟网络没有什么关系,真正的发送和接收是内核的事情,和应用程序无关。
至于阻塞还是非阻塞,出现的原因也不是为了得到接收端的确认,而是为了编写高效率的程序,io通常都是很慢的,非阻塞的作用就是让我们不用在等待io上浪费时间,而可以去做其它事情,例如操作其他io或者做一些逻辑处理。如果没有其他事情可做,那非阻塞也就失去意义了。
至于是否可靠,不是send的问题,而是事后接收协议回应包时再判断的问题。

论坛徽章:
0
63 [报告]
发表于 2007-07-31 15:49 |只看该作者
原帖由 福瑞哈哥 于 2007-7-31 14:30 发表

事实上,本次之前send也不能保证就是可靠发送了的。



对的,如果拨掉对端网线的话,在本次send之前的几次send,也还在本地缓存中...
但数据实际上发到网络上去了,只是没有得到ack确认,所以缓存中并没有删除它们...

论坛徽章:
0
64 [报告]
发表于 2007-07-31 15:52 |只看该作者
我正在看linux kernel network subsystem,看完了也许这贴我就有发言权了...

论坛徽章:
0
65 [报告]
发表于 2007-07-31 15:53 |只看该作者
原帖由 yulc 于 2007-7-31 15:49 发表



对的,如果拨掉对端网线的话,在本次send之前的几次send,也还在本地缓存中...
但数据实际上发到网络上去了,只是没有得到ack确认,所以缓存中并没有删除它们...


对你说的「数据实际上发到网络上去了」持保留意见。

论坛徽章:
0
66 [报告]
发表于 2007-07-31 16:09 |只看该作者
to 楼上,
我说的是拨掉对端的网线,这时候发送端是检测不到的,
所以肯定会将数据发到网络中,等待对端的确认.

论坛徽章:
0
67 [报告]
发表于 2007-07-31 16:14 |只看该作者
原帖由 yulc 于 2007-7-31 16:09 发表
to 楼上,
我说的是拨掉对端的网线,这时候发送端是检测不到的,
所以肯定会将数据发到网络中,等待对端的确认.


问题是有可能根本就没有发送。

论坛徽章:
0
68 [报告]
发表于 2007-07-31 16:24 |只看该作者
原帖由 福瑞哈哥 于 2007-7-31 16:14 发表


问题是有可能根本就没有发送。



不知道这个答复能不能说清楚.

我将192.168.0.229做为发送端, 192.168.0.226做为接收端,
当双方建立tcp后,将226主机的网线拨掉,在229上用tcpdump得出的结果是:

15:59:56.663510 IP 192.168.0.229.35986 > 192.168.0.226.3400: . 1:1449(1448) ack 1 win 1460 <nop,nop,timestamp 178712595 108716367>
15:59:56.663522 IP 192.168.0.229.35986 > 192.168.0.226.3400: . 1449:2897(1448) ack 1 win 1460 <nop,nop,timestamp 178712595 108716367>
15:59:56.866018 IP 192.168.0.229.35986 > 192.168.0.226.3400: . 1:1449(1448) ack 1 win 1460 <nop,nop,timestamp 178712646 108716367>
15:59:57.274042 IP 192.168.0.229.35986 > 192.168.0.226.3400: . 1:1449(1448) ack 1 win 1460 <nop,nop,timestamp 178712748 108716367>
15:59:58.090094 IP 192.168.0.229.35986 > 192.168.0.226.3400: . 1:1449(1448) ack 1 win 1460 <nop,nop,timestamp 178712952 108716367>
15:59:59.722196 IP 192.168.0.229.35986 > 192.168.0.226.3400: . 1:1449(1448) ack 1 win 1460 <nop,nop,timestamp 178713360 108716367>
16:00:02.986402 IP 192.168.0.229.35986 > 192.168.0.226.3400: . 1:1449(1448) ack 1 win 1460 <nop,nop,timestamp 178714176 108716367>


可以看出229首先向网络中发送了两个数据包,每个负载是1448bytes.
然后在200毫秒内,发现没有得到ack确认,再次发送了第一个数据包,然后经过大约400毫秒后再发了一次,
然后大约800毫秒后再发一次...
这个超时的值我认为取决于应用程序的设置,在linux默认应该是7200秒.

论坛徽章:
0
69 [报告]
发表于 2007-07-31 16:29 |只看该作者

回复 #68 yulc 的帖子

这个不能说明啊,因为现在想知道的是send返回时,是数据包发到网络的标志,还是送到buffer的标志。
上面的不能说明send返回时数据包已经发出还是在buffer里。(有可能是返回以后发的)

有个建议:利用上面抓到包的时间,和send返回的时间作下比较。

论坛徽章:
0
70 [报告]
发表于 2007-07-31 16:33 |只看该作者
原帖由 yulc 于 2007-7-31 16:24 发表



不知道这个答复能不能说清楚.

我将192.168.0.229做为发送端, 192.168.0.226做为接收端,
当双方建立tcp后,将226主机的网线拨掉,在229上用tcpdump得出的结果是:

15:59:56.663510 IP 192.168.0.229.3 ...


兄弟,你的这个系统发送了数据不代表所有的系统都会在send时发送啊。

如果前面的结论是正确的话,就是说send只负责拷贝数据到缓冲区,内核tcp负责发送,那就有可能在send返回后没有发送啊。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP