TCP流套接字使用send函数发送数据,send函数的返回值表示实际发送的数据大小。为什么要返回这样的一个值呢,难道不是把给定的缓冲区的数据全部发送出去吗?确实是这样。
send的函数实际上是把发送缓冲区的数据拷贝到系统发送数据缓冲区,当网络可以发送数据时,系统会自动从系统发送数据缓冲区读取数据发送,并删除已经发送过的数据,腾出空间给其他的socket发送数据。
假设send发送1024个字节的数据,而此时系统发送数据缓冲区如果只有512字节的空闲空间,那么send函数就只会拷贝512个字节的数据到系统发送数据缓冲区,并返回实际发送的数据为512.
这个时候,要想把所有数据全部发送出去,就必须再调用一次send函数来发送刚才没有拷贝到系统发送数据缓冲区中的512个字节的数据。
那么能保证第二次调用就能顺利把这512个字节的数据发送出去吗?显然不能。于是,就有了下面通用的做法:
对于recv接收数据也是同样的,recv是从系统接收数据缓冲区中把数据拷贝到用户接收数据缓冲区中。假设用户希望接收到1024字节的数据,而实际数据还没有全部到达接收端,系统接收缓冲区中只有512个字节的数据,此时recv就只能接收到512个数据。也许会想,同样的使用一个循环来接收数据,知道接收到想要的数据为止。这样想是不错,但是,接收端怎么知道应该接收多少数据才是正确的呢,希望的1024个字节的数据,依据是什么呢,这个时候,需要采取一个特殊处理,就是发送端在发送的时候,给数据加入一个包头,包头的最前面表示这包数据的大小。这样接收端接收到数据以后分析包头可达到预期接收数据的效果。