- 论坛徽章:
- 0
|
TCP的标准设计估计是帖子引用的那样。所以说send将数据COPY到buffer就返回了应该也没有问题。但是LINUX上的有些出入
我看了LINUX TCP代码,对于send ( tcp_sendmsg)有结论:
1)tcp_sendmsg 将数据COPY到buffer, 并不是(将发送任务交给TCP)立即返回。而是,根据情况判断,如果该发送了,自己启动网络设备发送,然后再返回。也就是说,TCP本身不是一个独立的消费者进程(象kblockd, aio那样,read/write路径将数据请求填充buffer, 然后就返回,等待它们读写磁盘完成), 我前面帖子给出的调用路径说明了这一点。----- 为什么要这么做?而不是如同“标准”说的那样?我分析主要是考虑效率。你想,USER APP send了100个字节,如果你将100个字节拷贝到buffer就返回,返回前势必通知TCP(KENREL THREAD,如果有的话)发送。这就有进程切换(代价比100个字节处理要浪费的多),自己直接做是最快的。
那为什么kblockd(磁盘)这样实现?磁盘是机械设备读写非常慢,有切换的代价也值得。而网卡不是机械的东西,将数据给网卡比给磁盘快的多。
2)tcp_sendmsg要对网络状态做许多检查,如果不能发送了,就给send许多关于网络的错误信息返回。
3)tcp_sendmsg只要填充了buffer(说明目前网络还没有什么问题),就会返回成功的字节数目。也即使说,无论启动网络设备发送的结果如何,对返回没有影响。所以send返回成功,根本不代表数据发送到对方了,仅仅代表到本地buffer了,或者已经送本地网络设备了。
原帖由 benjiam 于 2007-7-31 17:41 发表
好像没什么意义啊!
所谓的拔网线测试更是奇怪了。 没有意义。
在阻塞和非阻赛的时候 send 没什么区别的, 都是copy 栈里面。 就返回了。 没什么区别
关键在recv
[ 本帖最后由 思一克 于 2007-8-1 10:05 编辑 ] |
|