免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
0
1 [报告]
发表于 2007-07-31 10:19 |显示全部楼层
send 不仅仅是将内容放到自己buffer, 放后还要立即启动设备将包发出,即使buffer是相当空的。

原帖由 flw 于 2007-7-31 09:51 发表
【在阻塞模式下,send函数的过程是将应用程序请求发送的数据通过socket尽能力发送到对方接收缓存中(并非对方应用程),并返回成功发送的大小;】

这句话是错的吧?
我认为即使是在阻塞方式下,只要发送缓冲区还 ...

论坛徽章:
0
2 [报告]
发表于 2007-07-31 10:43 |显示全部楼层
send后,KERENL回立即启动dev发送.
write/send不会等待数据是否成功到达对方。
即使返回成功也不代表数据成功到达。
但返回错误却代表数据没有到达。



原帖由 flw 于 2007-7-31 10:22 发表

但那时 write/send 已经返回了。
它并不会等待发送结果的。
发送是 TCP 软件的功能,
write/send 只否则交付,
并不关心结果。

论坛徽章:
0
3 [报告]
发表于 2007-07-31 10:53 |显示全部楼层
但是send/write不是“仅仅负责COPY到本地buffer"其它就不管了(就交给TCP了),
send/write(网络)的内核代码多部分也属于TCP本身。
它们要启动实际发送,还要尽最大努力检查网络连接的状态,返回许多网络的信息给调用者。

原帖由 flw 于 2007-7-31 10:46 发表

那不就得了嘛。

论坛徽章:
0
4 [报告]
发表于 2007-07-31 11:11 |显示全部楼层
send 本身在内核部分的代码就是TCP和网络程序的一部分。

看帖子:

http://bbs.chinaunix.net/viewthr ... =%CB%BC%D2%BB%BF%CB


本机发出的报文
(route if need)dev_queue_xmit |
ip_finish_output2 |<POSTROUTING> ip_finish_output | ip_output | ip_dst_output | <LOCALOUT> ip_push_pending_frames | raw_sendmsg | inet_sendmsg | sock_sendmsg | sys_sendmsg | sys_socketcall | sysenter_past_esp

调用启动和网络的许多函数。

也就是说socket write /send 和网络是在一起的,而没有一个清晰的buffer, send/write放入,网络程序取出那样的清晰的生产消费过程(虽然可以在一定程度上理解为生产/消费)

论坛徽章:
0
5 [报告]
发表于 2007-07-31 11:24 |显示全部楼层
好象不是你说的这样。

你可以实验,写一个阻塞的TCP,先send 1 个字节(1次),成功后将NIC 拔掉,然后再SEND 1个字节(2次), 然后再1个字节(3次)

2次可以返回成功的。3次失败。

该问题同原来争吵的feof问题道理一样。

原帖由 醉卧水云间 于 2007-7-31 11:03 发表
建议flw还是去补习一下网络编程吧,阻塞模式下,必须发到对端函数才返回。

论坛徽章:
0
6 [报告]
发表于 2007-07-31 11:53 |显示全部楼层
send 可能要将一个字节经过很多设备发送到地球那一边。而且有时候网络又很慢。不可能等完成。再说了,只要对方不发确认,你如何知道完成了? 发了确认都未必见得是真的。

所以拔网络线后第2次可以成功返回没有什么问题。设计的就是这样的。而通过第2次,才有第3次的失败。

原帖由 醉卧水云间 于 2007-7-31 11:48 发表


你这是欺骗系统的方式,拔掉网线后系统知道被拔是需要时间的。你可以等一段时间再发送试试,结果应不同。

还有就是系统因为效率上的原因,没有严格按send语意来做,send语意就是返回成功就是保证发送成功 ...

论坛徽章:
0
7 [报告]
发表于 2007-07-31 11:58 |显示全部楼层
man send.

RETURN VALUE
       On  success,  these  calls return the number of characters sent.  On error, -1 is
       returned, and errno is set appropriately.

成功代表内容被成功地传输到网络了,不代表到达远方目的地。

还有看以下如此多的错误返回,也可以知道send绝对不是将内容放到本地buffer就返回(只要buffer有空间就成功返回)那样简单。


ERRORS
       These are some standard errors generated by the socket layer.  Additional  errors
       may  be  generated  and  returned from the underlying protocol modules; see their
       respective manual pages.

       EACCES (For Unix domain sockets, which are identified by pathname) Write  permisâ

论坛徽章:
0
8 [报告]
发表于 2007-07-31 13:55 |显示全部楼层
你们说的发送缓冲区是setsockopt 的 SO_SNDBUF吗?




原帖由 醉卧水云间 于 2007-7-31 13:27 发表


我觉得这样更好一些:

阻塞send是可靠的发送,但为了发送的效率,最后一部分buf能容纳的数据不会要求对方确认,而是假设这部分包将来会成功发送到对方,因为短期内我们预期网络连接不会存在问题,这部分 ...

论坛徽章:
0
9 [报告]
发表于 2007-07-31 14:17 |显示全部楼层
TCP阻塞send是可靠发送,意思是如果连续send成功返回,那么本次send之前的是可靠发送了的。而刚才(本次)的还是不知道。

拔NIC电缆的实验已经证明了。

还有KENREL中其实没有一个专门为了缓冲发送内容的的很大的buffer(比如8192)。有的是skb在内核中的数据。其目的也不是为了缓存,而是为了实现网络功能的数据结构------没有它不可以。如果是缓存,那么就可以没有(比如文件系统的缓存,DIRECT-IO就可以使其根本不起作用)。但skb不行。

还有SO_SNDBUF最小2048,不可能为0。因为它本来不是做cache/buffer的意义。




原帖由 醉卧水云间 于 2007-7-31 13:27 发表


我觉得这样更好一些:

阻塞send是可靠的发送,但为了发送的效率,最后一部分buf能容纳的数据不会要求对方确认,而是假设这部分包将来会成功发送到对方,因为短期内我们预期网络连接不会存在问题,这部分 ...

论坛徽章:
0
10 [报告]
发表于 2007-07-31 14:35 |显示全部楼层
也有可能
你实验看,拿出验证方法。

原帖由 福瑞哈哥 于 2007-7-31 14:30 发表

事实上,本次之前send也不能保证就是可靠发送了的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP