send后,KERENL回立即启动dev发送.
write/send不会等待数据是否成功到达对方。
即使返回成功也不代表数据成功到达。
但返回错误却代表数据没有到达。
通常tcp应用是需要交互的,所以在编程实现中,如果采用非阻塞方式,一般是用select来检测socket是否可读/可写的.
你总不能在非阻塞的状态下这样写吧,如果你不怕累死CPU的话.
while(1)
{
send();
if(err != EAGAIN)
break;
eles
continue;
}
所以,一般是写成这样:
while(1)
{
select();
if(可读)
read();
if(可写)
recv();
...
}
原帖由 思一克 于 2007-7-31 11:11 发表
本机发出的报文
(route if need)dev_queue_xmit |
ip_finish_output2 |
ip_finish_output | ip_output | ip_dst_output | ip_push_pending_frames | raw_sendmsg | inet_sendmsg | sock_sendmsg | sys_sendmsg | sys_socketcall | sysenter_past_esp
具体到这里,就是实现相关了,Linux 的实现一向以糟糕著称,没准儿等 2.8 又会变成什么样子,而且,对于应用层程序员来说,他看不到这些。
总而言之,从逻辑上来看,send/write 的作用,就是把数据放入发送缓冲区,然后返回。至于它如何通知 TCP 来发送,以及 TCP 又如何发送,发送结果是什么,都不影响 send/write 的语义
对,在阻塞模式下是这样的,send将数据发到网络上就ok了,不必等ack。而且一般tcp的实现是2次一个ack,所以要马上收到ack是不可能的。
非阻塞的时候好像就是拷贝到缓冲区。
还有一个证明,就是有个SO_SNDBUG,设为0的时候。数据应该会这接发出去吧。
所来说去,buffer在这里起重要作用。
阻塞send本意是要发到对方确认的,但唯独buffer能容纳的那部分它不会被立刻发出确认。但它的主意很显然是一个需要对方确认的发送。
阅读(5851) | 评论(0) | 转发(0) |