免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
0
11 [报告]
发表于 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
12 [报告]
发表于 2007-07-31 16:43 |显示全部楼层

回复 #69 icydancer 的帖子

"这个不能说明啊,因为现在想知道的是send返回时,是数据包发到网络的标志,还是送到buffer的标志。"
这个我认为要看当前发送端是什么状态,如果之前还有包没有得到确认,那么此次send肯定仅仅是送到buffer.


"上面的不能说明send返回时数据包已经发出还是在buffer里。(有可能是返回以后发的)"
这个有什么关系吗?

论坛徽章:
0
13 [报告]
发表于 2007-07-31 16:52 |显示全部楼层
原帖由 福瑞哈哥 于 2007-7-31 16:33 发表


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

如果前面的结论是正确的话,就是说send只负责拷贝数据到缓冲区,内核tcp负责发送,那就有可能在send返回后没有发送啊。



确实有可能,如果此时前面还有很多数据没有确认的情况下.

论坛徽章:
0
14 [报告]
发表于 2007-07-31 16:54 |显示全部楼层
原帖由 baohuaihuai 于 2007-7-31 16:45 发表
各位顺便讲解一下这个的过程(假设接收缓冲区和发送缓冲区都是8K,网络情况良好):

time1:发送端send 8K,接收端应用程序不recv
time2:接收端recv 2K.
time3:发送端send 8K.
time4:接收端recv 14K.



结果:
time1: 发送端将8k数据分为N个数据包发送到了接收端的缓存中,接收端等待应用程序recv;
time2: 接收端收到了2k,缓存中还有6k;
time3: 发送端又将8k数据分N个包到接收端的接收缓存中;
time4: 接收端得到了14k数据.

论坛徽章:
0
15 [报告]
发表于 2007-07-31 17:00 |显示全部楼层
原帖由 icydancer 于 2007-7-31 16:52 发表

有关系,现在大家想知道的是,send是将数据发到网络后再返回?还是仅仅将数据放到buffer后就马上返回?
你上面的数据不能说明这一点



我认为这个是不可确定的..

论坛徽章:
0
16 [报告]
发表于 2007-07-31 17:01 |显示全部楼层
原帖由 baohuaihuai 于 2007-7-31 16:56 发表


time3过后,发送缓冲区中有多少字节的数据?是8K?6K?



time3过后,发送缓存中为0,因为得到了接收端的ack了.

论坛徽章:
0
17 [报告]
发表于 2007-07-31 17:06 |显示全部楼层
原帖由 icydancer 于 2007-7-31 16:55 发表

看来我的表达能力太差了 福瑞一说你就能明白



其实我在回复你贴子时也在自我进化..
很多时候,我在给别人解释一个东西时,发现原来自己也理解得不够透,或者在说着说着时瞬间理解透...

论坛徽章:
0
18 [报告]
发表于 2007-07-31 21:45 |显示全部楼层
原帖由 baohuaihuai 于 2007-7-31 17:10 发表

可是接收缓存已经满了啊



sorry,我不够仔细,我没有看到你所设的接收缓存是8k
这样的话,我想情况会是这样的:
由于第一次过后,缓存中还有2k的空间,所以会在ack包中告诉发送端我的滑动窗口大小为2048bytes,
这时,发送端会发一个约为1500(假设MTU为1500)大小的包过来,然后再是一个500字节的包.
这时候,如果接收应用程序还没有调用recv来获取缓存中的数据,
那么接收端会在ack中通知发送端滑动窗口已为0,需要它暂停发送.

论坛徽章:
0
19 [报告]
发表于 2007-07-31 21:59 |显示全部楼层
原帖由 xiaxueyi 于 2007-7-31 17:57 发表
你们讨论得这么复杂,我问个简单的问题
在非阻塞的情况下,应用程序调用send发送数据后返回,在不与接收端再次通讯的情况下,如何知道内核有没有把发送端缓冲区的数据发出去?如果没有,如何知道错误原因?



在程序中我不知道如何得到,哪位知道,请告诉我.
我只会用netstat -a 查看, Send-Q 那列就是.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP