**在tcp编程中,我们以服务端为发送端,客户端为接收端举例。通信过程中发送端和接收端都有一个接收缓冲区和发送缓冲区(也就是说一边两个缓冲区),在编程过程中当我们使用send方法的时候所做的工作就是—-将程序中的数据发送到计算机内核的发送缓冲区,而当我们使用recv()方法时就是—将接收缓冲区中的数据读取到程序中。而真正的数据交互就是tcp协议和计算机内核去完成了与我们的编程程序无关。
下面说几种情况:**
1、发送端多次发送的数据,接收端可一次接受,说明tcp消息是没有消息边界的,
同时也说明tcp编程不是发送端发送一次消息对应接收端接收一次消息,同时还说
明接收端和发送端都有相应的收发缓冲区(tcp全双工)。
2、当自身接收缓冲区存在数据时,自身此时关闭socket对象,也就是说接收缓
冲区还有数据没有被应用程序读时,会直接发送RST包到对端,有可能导致对端的
应用程序正在读取tcp缓冲区数据,却突然收到RST包,导致对端tcp丢弃发送和
接收缓冲区里的所有数据,应该程序会丢数据。
3、当自身接收缓冲区存在数据时,对端此时关闭socket对象,此时断开连接,
但是还是可以从自身接收缓冲区中读取数据,不受影响。
4、如果在close时,发送缓冲区中有数据还没有发送出去,本端应用程序无法确认,
对端tcp是否能收到(仅由tcp的机制实现安全交付)
5、send()只是负责拷贝,拷贝完立即返回,不会等待发送和发送之后的ACK。
如果socket出现问题,RST包被反馈回来。在RST包返回之时,如果send()还
没有把数据全部放入内核或者发送出去,那么send()返回-1,errno被置错误
值;如果RST包返回之时,send()已经返回,那么RST导致的错误会在下一次
send()或者recv()调用的时候被立即返回。
**
**
概念上容易疑惑的地方
(出自于http://www.cnblogs.com/my_life/articles/5363527.html再次深入理解TCP网络编程中的send和recv)
**
**1. TCP协议本身是为了保证可靠传输,并不等于应用程序用tcp发送数据就一定是可靠的,必须要容错;
2. send()和recv()没有固定的对应关系,不定数目的send()可以触发不定数目的recv(),这话不专业,但是还是必须说一下,初学者容易疑惑;
3. 关键点,send()只负责拷贝,拷贝到内核就返回,我通篇在说拷贝完返回,很多文章中说send()在成功发送数据后返回,成功发送是说发出去的东西被ACK确认过。send()只拷贝,不会等ACK;
4. 此次send()调用所触发的程序错误,可能会在本次返回,也可能在下次调用网络IO函数的时候被返回。**
欢迎指正!!!谢谢