TCP/IP (二) TCP消息的发送
2015-11-20 19:41
471 查看
和上一篇文章一样,带着一些问题来思考TCP的消息发送
1.已经建立好的tcp连接,先发送数据包data1,再发送数据包data2,数据包data2会不会比数据包先到达?
2.发送send函数和write函数有什么区别?调用发送函数后内核发生了什么事情?
3.发送方法成功返回时,是否能保证数据已经发送出去,是否能保证对端一定收到?
4.套接字为阻塞或者非阻塞时,发送方法做的事情有何不同?
在发送层面,TCP内核做了哪些操作,借用陶大师的图:
![](https://img-blog.csdn.net/20151120195603692)
来看看数据发送的步骤:
1.调用send函数
2.数据复制至内核态
3.假设缓冲区满了,非阻塞模式send函数会返回errno ==EAGAIN,意味着数据尚未发送请重试,阻塞模式send函数则会等待
4.send函数返回成功,可能是部分发送成功,可能是全部发送成功,并不意味着数据已经发送到网络上,也不意味着对端收到数据了,只是说明内核试图把数据发送至对端。TCP的可靠性是要求连接对端在接收到数据后发送ACK进行确认,告诉发送端已经接收到了多少字节的数据。所以确保数据的发送成功,是依赖于ACK的抵达,才能确保数据的发送成功。
内核中为这个TCP连接分配的内核缓存是有限的,关于缓冲区的大小设置,并不是越大越好也不是越小越好,可以根据业务的特性进行调优。
阻塞模式下的send函数并没有超时参数,通过setsockopt()函数设置超时
已经建立好的tcp连接,先发送数据包data1,再发送数据包data2,数据包data2会不会比数据包先到达?
TCP并没有数据包的概念,是完全流式的,它会开辟一个缓冲区,每隔一段时间就会发送出去,由于数据在链路层的分片,data1的数据是有可能比data2先达到对端的接收缓冲区,但是如果对端调用接收函数时,是不可能发生先收到data2再收到data1,在下一篇TCP消息的接收将会说明这个问题。
send函数和write函数的区别,我们来看看男人是怎么说的,The only difference between send() and write(2) is the presence offlags. With a zero flags argument,send() is equivalent to write(2).
多线程并发对同一个socket连接进行发送数据操作时,是否要加锁?
发送首先会对缓存加锁.通过加锁确保多个进程按序互斥访问插口缓存.(tcp/ip 卷2, page 394,395),也就是说内核会对缓冲区加锁,但是我们要考虑一个问题,当缓冲区不足以装下所有的并发发送数据时,那么数据就可能出现乱序,所有并不建议并发对同一个连接操作。
参考资料:《tcp/ip详解卷1》
参考文章:http://blog.csdn.net/russell_tao/article/details/9370109
1.已经建立好的tcp连接,先发送数据包data1,再发送数据包data2,数据包data2会不会比数据包先到达?
2.发送send函数和write函数有什么区别?调用发送函数后内核发生了什么事情?
3.发送方法成功返回时,是否能保证数据已经发送出去,是否能保证对端一定收到?
4.套接字为阻塞或者非阻塞时,发送方法做的事情有何不同?
在发送层面,TCP内核做了哪些操作,借用陶大师的图:
来看看数据发送的步骤:
1.调用send函数
2.数据复制至内核态
3.假设缓冲区满了,非阻塞模式send函数会返回errno ==EAGAIN,意味着数据尚未发送请重试,阻塞模式send函数则会等待
4.send函数返回成功,可能是部分发送成功,可能是全部发送成功,并不意味着数据已经发送到网络上,也不意味着对端收到数据了,只是说明内核试图把数据发送至对端。TCP的可靠性是要求连接对端在接收到数据后发送ACK进行确认,告诉发送端已经接收到了多少字节的数据。所以确保数据的发送成功,是依赖于ACK的抵达,才能确保数据的发送成功。
内核中为这个TCP连接分配的内核缓存是有限的,关于缓冲区的大小设置,并不是越大越好也不是越小越好,可以根据业务的特性进行调优。
阻塞模式下的send函数并没有超时参数,通过setsockopt()函数设置超时
已经建立好的tcp连接,先发送数据包data1,再发送数据包data2,数据包data2会不会比数据包先到达?
TCP并没有数据包的概念,是完全流式的,它会开辟一个缓冲区,每隔一段时间就会发送出去,由于数据在链路层的分片,data1的数据是有可能比data2先达到对端的接收缓冲区,但是如果对端调用接收函数时,是不可能发生先收到data2再收到data1,在下一篇TCP消息的接收将会说明这个问题。
send函数和write函数的区别,我们来看看男人是怎么说的,The only difference between send() and write(2) is the presence offlags. With a zero flags argument,send() is equivalent to write(2).
多线程并发对同一个socket连接进行发送数据操作时,是否要加锁?
发送首先会对缓存加锁.通过加锁确保多个进程按序互斥访问插口缓存.(tcp/ip 卷2, page 394,395),也就是说内核会对缓冲区加锁,但是我们要考虑一个问题,当缓冲区不足以装下所有的并发发送数据时,那么数据就可能出现乱序,所有并不建议并发对同一个连接操作。
参考资料:《tcp/ip详解卷1》
参考文章:http://blog.csdn.net/russell_tao/article/details/9370109
相关文章推荐