您的位置:首页 > 理论基础 > 计算机网络

TCP/IP (二) TCP消息的发送

2015-11-20 19:41 471 查看
上一篇文章一样,带着一些问题来思考TCP的消息发送

 

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

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息