TCP套接字的数据收发无边界。服务器端即使调用1次write函数传输40字节的数
据,客户端也有可能通过4次read 函数调用每次读取10字节。但此处也有一些疑问,服务器端一
次性传输了40字节,而客户端居然可以缓慢地分批接收。客户端接收10字节后,剩下的30字节在
何处等候呢?是不是像飞机为等待着陆而在空中盘旋一样,剩下30字节也在网络中徘徊并等待接
收呢?
实际上, write 函数调用后并非立即传输数据, read函数调用后也并非马上接收数据。更准确
地说,如下图所示, write函数调用瞬间,数据将移至输出缓冲; read函数调用瞬间,从输入缓冲
读取数据。
如上图
所示,调用
write
函数时 数据将移到输出缓冲,在适当的时候(不管是分别传送还
次性传送)传向对方的输入缓冲
这时对方将调用
read
函数从输入缓冲读取数据。
这些
I/O
缓冲特性可整理
如下:
I/O缓
冲在每个TCP
套接字中单独存在;
I/O
缓冲在
创建
套接字
自动生成;
即使
关闭套接字也会继续传递输出缓冲
中遗留的数据;
关闭套接字将丢失输入缓冲中的数据;
那么,下面这种情况会引发什么事情?理解了I/O缓冲后,各位应该可以猜出其流程:
"客户端输入缓冲为
50
字节,而服务器端传输了
100
字节。
可以提出如下解决方案:
.
"填满输入缓冲前迅速调用read函数读取数据,这样会腾出一部分空间,问题就解
决了。"
当然,这只是我的一个小玩笑,相信大家不会当真,那么马上给出结论:
"不会发生超过输入缓冲大小的数据传输。"
也就是说,根本不会发生这类问题,因为TCP会控制数据流。TCP中有滑动窗口( Sliding
Window) 协议,用对话方式呈现如下。
.
"填满输入缓冲前迅速调用read函数读取数据,这样会腾出一部分空间,问题就解
决了。"
当然,这只是我的一个小玩笑,相信大家不会当真,那么马上给出结论:
"不会发生超过输入缓冲大小的数据传输。"
也就是说,根本不会发生这类问题,因为TCP会控制数据流。TCP中有滑动窗口( Sliding
Window) 协议,用对话方式呈现如下。
套接字A:"你好,最多可以向我传递50字节。"
套接字B: "OK!"
套接字A: "我腾出了20字节的空间,最多可以收70 字节。"
套接字B: "OK!"
数据收发也是如此,因此TCP中不会因为缓冲溢出而丢失数据。
socket中write
函数返回的时间点:
write
函数和
Windows
send
函数并不会在完成向对方主机的数据传输时
返回,而是在数据移到输出缓冲时。但
TCP
会保证对输出缓冲数据的传输,
所以说
write
函数在数据传输完成时返回。要准确理解这句话。
TCP数据传输中不存在边界,这表示"数据传输过程中调用I/O函数的次数不具有任何意义。"
相反‘ UDP是具有数据边界的协议,传输中调用I/O函数的次数非常重要。因此,输入函数
的调用次数应和输出函数的调用次数完全一致,这样才能保证接收全部已发送数据。例如,调用
3次输出函数发送的数据必须通过调用3次输入函数才能接收完。
相反‘ UDP是具有数据边界的协议,传输中调用I/O函数的次数非常重要。因此,输入函数
的调用次数应和输出函数的调用次数完全一致,这样才能保证接收全部已发送数据。例如,调用
3次输出函数发送的数据必须通过调用3次输入函数才能接收完。