这4个名词的解释网络上有很多种版本和很多种比喻,个人不太喜欢打比方的方式来理解技术问题,因为很难有贴切的比喻,稍不注意就把人带到沟里.我们这里只通过技术模型来理解这4个术语,忽略这些名词广义上的定义,通过分析下面这个具体的场景来分享下我对他们的理解:
场景:假设要通过一个socket发送的数据是5k大小的一段文本,内核的发送缓冲区4k.
首先要搞明白一个基础问题,当我们在socket上调用一个发送操作时(send/write),虽然我们希望将数据发送到网络另一端,但是对于操作系统来说,它只要把用户态的数据成功拷贝到内核的发送缓冲区中排队等待发送,就可以给用户态的程序一个最后的交代了,操作系统给用户态发送的所有通知信息都是表明数据拷贝完成情况的,而操作系统从来不保证你的这些数据已经被网络另一端读取到了.即使对方读取到了,应用层也不会再获得什么通知.应用层完全无法获知数据是否真的到达了网络另一端.当在一个socket连接上应用写操作时,最好理解为拷贝数据到发送队列中并通知TCP队列中有了新数据(参考:高级TCP/IP编程15节)
只从数据角度考虑,socket的发送函数最主要的参数就是一块用户态内存(void* buf, int length).对于发送操作(send/write),我们可以从下面两个方面理解
1 函数调用完成后 多少数据拷贝完毕
2 如果发送的数据超出发送缓冲区的大小,调用过程和影响是怎样的
1 阻塞
内核首先将5k里的前4k数据拷贝到发送缓冲区,4k拷贝完成后,要等待4k中的数据里最前端的1k数据发送到网络并且得到了对方SYN确认后,内核确认对方已经收到了这1k的数据,于是将这1k数据从缓冲区中清除,这样空余出1k的缓冲区,然后内核将剩余的1k数据拷贝到发送缓冲区,此后send/write返回.注意这里不会再等待剩余数据被对端接受才返回,因为数据已经拷贝到缓冲区,任务完成了可以给用户态交代了.待send/write返回后,用户态的5k数据对内核来说已经失效了,因为5k数据里
场景:假设要通过一个socket发送的数据是5k大小的一段文本,内核的发送缓冲区4k.
首先要搞明白一个基础问题,当我们在socket上调用一个发送操作时(send/write),虽然我们希望将数据发送到网络另一端,但是对于操作系统来说,它只要把用户态的数据成功拷贝到内核的发送缓冲区中排队等待发送,就可以给用户态的程序一个最后的交代了,操作系统给用户态发送的所有通知信息都是表明数据拷贝完成情况的,而操作系统从来不保证你的这些数据已经被网络另一端读取到了.即使对方读取到了,应用层也不会再获得什么通知.应用层完全无法获知数据是否真的到达了网络另一端.当在一个socket连接上应用写操作时,最好理解为拷贝数据到发送队列中并通知TCP队列中有了新数据(参考:高级TCP/IP编程15节)
只从数据角度考虑,socket的发送函数最主要的参数就是一块用户态内存(void* buf, int length).对于发送操作(send/write),我们可以从下面两个方面理解
1 函数调用完成后 多少数据拷贝完毕
2 如果发送的数据超出发送缓冲区的大小,调用过程和影响是怎样的
1 阻塞
内核首先将5k里的前4k数据拷贝到发送缓冲区,4k拷贝完成后,要等待4k中的数据里最前端的1k数据发送到网络并且得到了对方SYN确认后,内核确认对方已经收到了这1k的数据,于是将这1k数据从缓冲区中清除,这样空余出1k的缓冲区,然后内核将剩余的1k数据拷贝到发送缓冲区,此后send/write返回.注意这里不会再等待剩余数据被对端接受才返回,因为数据已经拷贝到缓冲区,任务完成了可以给用户态交代了.待send/write返回后,用户态的5k数据对内核来说已经失效了,因为5k数据里