首页 > 代码库 > 【网络协议】TCP的交互数据流和成块数据流
【网络协议】TCP的交互数据流和成块数据流
前言
建立在TCP协议上的应用层协议有很多,如FTP、HTTP、Telnet等,这些协议根据传输数据的多少可以分为两类:交互数据类型和成块数据类型。
交互数据类型,如:Telnet,这类协议一般只做小流量的数据交换,比如每按下一个键,要回显一些字符。
成块数据类型,如:FTP,这类协议需要传输的数据比较多,一般传输的数据量比较大。
针对这两种不同的情况,TCP采用不同的策略进行数据传输。
交互数据流
针对交互性要求比较高的应用,比如Rlogin远程登录中,需要回显客户端输入的字符,每发送一个字节到服务端,并回显到客户端的过程如下:
1、客户端产生一个41bit长的报文(20字节的IP首部,20字节的TCP首部,1字节的数据),发送到服务端;
2、服务端发送过来一个40bit的确认报文;
3、服务端发送回显的字符,报文长为41bit;
4、客户端发送确认报文,报文长为40bit。
如果在局域网中,通常不会有什么麻烦,因为局域网一般不会出现拥塞,但在广域网中,这些小分组则会增加网络拥塞出现的可能。为了提高这类数据的发送效率和降低网络负担,TCP采用了两种策略:捎带ACK和Nagle算法。
捎带ACK
捎带ACK的意思是,当接收端接收到TCP报文段后,并不立即发送ACK报文,而是等上一段时间,如果这段时间里该主机有数据要发送到远程主机,就将该数据捎带上ACK一起发送过去,很明显,这样可以减少传输开销。为了防止产生超时重传,绝大多数情况下,这个等待时间为200ms,超过了200ms,如果没有数据要一起发送,就直接发送ACK报文。
捎带ACK的策略一般也只有在交互性比较高的应用中才会使用,对于成块数据流,一般大多数应用程序不会同时在两个方向上发送数据。
Nagle算法
该算法的重点是要求在TCP连接上组多只能有一个未被确认的数据报在传输。算法的大致思路如下:应用程序把要发送的数据逐个字节地从到TCP的发送缓存,发送方把线面的一部分数据先发送出去,并把后面到达的字节继续缓存起来,当发送方收到前面字节的确认后,再把发送缓冲中的所有数据组装成一个报文段发送出去,同时继续对随后到来的数据进行缓存。只有收到前一个报文段的确认后才能继续发送下一个报文段。另外,Nagle算法还规定,当发送缓存中的数据已达到发送窗口大小的一半或已达到报文段的MSS值时,就立即发送一个报文段。
当数据到达较快而网络速率较慢时,用这种方法可明显地减少所用的网络带宽。很明显,该算法也是专门为交互性高的应用而设计的,对于成块数据流,如果每收到一次确认才能发送下一个报文段,那么传输速率就会很低。
成块数据流
对于一些数据吞吐量要求较高的应用,总是希望每次发送尽可能多的数据到主机,对于这类应用,TCP使用滑动窗口协议,该协议允许发送方在停止发送前和等待确认前可以连续发送多个分组,因此可以加速数据的传输。
滑动窗口
滑动窗口的滑动是以字节为单位的,发送方A和接收方B在TCP三次握手的前两次握手时协商好了发送窗口和接受窗口的大小,发送方A根据B发送来的确认连接报文中标明的窗口的大小,来确定收到确认前的最大发送数据量,如果A接收到的B发来的确认报文中标明的窗口大小为0,则停止发送数据,直到收到不为0的确认报文,再继续发送。发送窗口表示在没有收到B的确认的情况下,A可以连续把窗口内的数据都发送出去,凡是已发送过的数据,在没有收到确认前都要暂时保留,以便超时重传时使用。
需要注意的一点是:使用TCP滑动窗口协议时,接收方不必确认每一个收到的分组,在TCP中,ACK确认是累积的,可以在接收到几个序号连续的报文段后只发送一个ACK确认报文,但累积等待的时间最长不能超过0.5秒,以防止发送端超时重传。
另外,要注意滑动窗口的三种变化:
1、窗口合拢。窗口左边沿向右边沿靠近,这种情况发生在数据被发送后收到确认时;
2、窗口张开。窗口右边沿向右移动,说明允许发送更多的数据,这种情况发生在另一端的接收进程从TCP接收缓存中读取了已经确认的数据时;
3、窗口收缩。窗口右边沿向左移动,一般很少发生,RFC也强烈不建议这么做,因为很可能会产生一些错误,比如一些数据已经发送出去了,又要收缩窗口,不让发送这些数据。
另外,窗口的左边沿是肯定不可能左移的,如果接收到一个指示窗口左边沿向左移动的ACK,则它被认为是一个重复ACK,并被丢弃。
总结以下几点:
1、发送方不必发送一个全窗口大小的数据,一次发送一部分即可。
2、窗口的大小可以减小,但是窗口的右边沿却不能向左移动。
3、接收方在发送一个ACK前不必等待窗口被填满。
4、窗口的大小是相对于确认序号的,收到确认后的窗口的左边沿从确认序号开始。
发送接收缓冲区
本部分主要明确一下几点:
1、缓冲空间和序号空间都是有限的,并且都是循环使用的。
2、窗口大小一定不大于收发缓冲区的大小
3、发送缓冲区用来暂存发送方准备发送的TCP报文段和已发送但尚未收到确认的数据。
4、接收缓冲区用来暂按序到达但尚未被上层应用程序读取的数据合未按序到达的数据。