《Linux高性能服务器编程》——3.6 TCP交互数据流

3.6 TCP交互数据流

前面讨论了TCP连接及其状态,从本节开始我们讨论通过TCP连接交换的应用程序数据。TCP报文段所携带的应用程序数据按照长度分为两种:交互数据和成块数据。交互数据仅包含很少的字节。使用交互数据的应用程序(或协议)对实时性要求高,比如telnet、ssh等。成块数据的长度则通常为TCP报文段允许的最大数据长度。使用成块数据的应用程序(或协议)对传输效率要求高,比如ftp。本节我们讨论交互数据流。

考虑如下情况:在ernest-laptop上执行telnet命令登录到本机,然后在shell命令提示符后执行ls命令,同时用tcpdump抓取这一过程中telnet客户端和telnet服务器交换的TCP报文段。具体操作过程如下:

$ tcpdump –nt –i lo port 23
$ telnet 127.0.0.1
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Ubuntu 9.10
ernest-laptop login: ernest(回车) #输入用户名并回车
Password:(回车)               #输入密码并回车

ernest@ernest-laptop:~$ ls(回车)

上述过程将引起客户端和服务器交换很多TCP报文段。下面我们仅列出我们感兴趣的、执行ls命令产生的tcpdump输出,如代码清单3-4所示。

TCP报文段1由客户端发送给服务器,它携带1个字节的应用程序数据,即字母“l”。TCP报文段2是服务器对TCP报文段1的确认,同时回显字母“l”。TCP报文段3是客户端对TCP报文段2的确认。第4~6个TCP报文段是针对字母“s”的上述过程。TCP报文段7传送的2字节数据分别是:客户端键入的回车符和流结束符(EOF,本例中是0x00)。TCP报文段8携带服务器返回的客户查询的目录的内容(ls命令的输出),包括该目录下文件的文件名及其显示控制参数。TCP报文段9是客户端对TCP报文段8的确认。TCP报文段10携带的也是服务器返回给客户端的数据,包括一个回车符、一个换行符、客户端登录用户的PS1环境变量(第一级命令提示符)。TCP报文段11是客户端对TCP报文段10的确认。

在上述过程中,客户端针对服务器返回的数据所发送的确认报文段(TCP报文段6、9和11)都不携带任何应用程序数据(长度为0),而服务器每次发送的确认报文段(TCP报文段2、5、8和10)都包含它需要发送的应用程序数据。服务器的这种处理方式称为延迟确认,即它不马上确认上次收到的数据,而是在一段延迟时间后查看本端是否有数据需要发送,如果有,则和确认信息一起发出。因为服务器对客户请求处理得很快,所以它发送确认报文段的时候总是有数据一起发送。延迟确认可以减少发送TCP报文段的数量。而由于用户的输入速度明显慢于客户端程序的处理速度,所以客户端的确认报文段总是不携带任何应用程序数据。前文曾提到,在TCP连接的建立和断开过程中,也可能发生延迟确认。

上例是在本地回路运行的结果,在局域网中也能得到基本相同的结果,但在广域网就未必如此了。广域网上的交互数据流可能经受很大的延迟,并且,携带交互数据的微小TCP报文段数量一般很多(一个按键输入就导致一个TCP报文段),这些因素都可能导致拥塞发生。解决该问题的一个简单有效的方法是使用Nagle算法。

Nagle算法要求一个TCP连接的通信双方在任意时刻都最多只能发送一个未被确认的TCP报文段,在该TCP报文段的确认到达之前不能发送其他TCP报文段。另一方面,发送方在等待确认的同时收集本端需要发送的微量数据,并在确认到来时以一个TCP报文段将它们全部发出。这样就极大地减少了网络上的微小TCP报文段的数量。该算法的另一个优点在于其自适应性:确认到达得越快,数据也就发送得越快。

时间: 2024-12-22 21:16:47

《Linux高性能服务器编程》——3.6 TCP交互数据流的相关文章

《Linux高性能服务器编程》——导读

前 言 为什么要写这本书 目前国内计算机书籍的一个明显弊病就是内容宽泛而空洞.很多书籍长篇大论,恨不得囊括所有最新的技术,但连一个最基本的技术细节也无法解释清楚.有些书籍给读者展现的是网络上随处可见的知识,基本没有自己的观点,甚至连一点自己的总结都没有.反观大师们的经典书籍,整本书只专注于一个问题,而且对每个技术细节的描述都是精雕细琢.最关键的是,我们在阅读这些经典书籍时,似乎是在用心与一位编程高手交流,这绝对是一种享受. 我们把问题缩小到计算机网络编程领域.关于计算机网络编程的相关书籍,不得不

《Linux高性能服务器编程》——3.3 TCP连接的建立和关闭

3.3 TCP连接的建立和关闭 本节我们讨论建立和关闭TCP连接的过程. 3.3.1 使用tcpdump观察TCP连接的建立和关闭 首先从ernest-laptop上执行telnet命令登录Kongming20的80端口,然后抓取这一过程中客户端和服务器交换的TCP报文段.具体操作过程如下: $ sudo tcpdump -i eth0 –nt '(src 192.168.1.109 and dst 192.168.1.108) or (src 192.168.1.108 and dst 192

《Linux高性能服务器编程》——3.9 TCP超时重传

3.9 TCP超时重传 在3.6节-3.8节中,我们讲述了TCP在正常网络情况下的数据流.从本节开始,我们讨论异常网络状况下(开始出现超时或丢包),TCP如何控制数据传输以保证其承诺的可靠服务. TCP服务必须能够重传超时时间内未收到确认的TCP报文段.为此,TCP模块为每个TCP报文段都维护一个重传定时器,该定时器在TCP报文段第一次被发送时启动.如果超时时间内未收到接收方的应答,TCP模块将重传TCP报文段并重置定时器.至于下次重传的超时时间如何选择,以及最多执行多少次重传,就是TCP的重传

《Linux高性能服务器编程》——第1章 TCP/IP协议族 1.1 TCP/IP协议族体系结构以及主要协议

第1章 TCP/IP协议族 现在Internet(因特网)使用的主流协议族是TCP/IP协议族,它是一个分层.多协议的通信体系.本章简要讨论TCP/IP协议族各层包含的主要协议,以及它们之间是如何协作完成网络通信的. TCP/IP协议族包含众多协议,我们无法一一讨论.本书将在后续章节详细讨论IP协议和TCP协议,因为它们对编写网络应用程序具有最直接的影响.本章则简单介绍其中几个相关协议:ICMP协议.ARP协议和DNS协议,学习它们对于理解网络通信很有帮助.读者如果想要系统地学习网络协议,那么R

《Linux高性能服务器编程》——3.4 TCP状态转移

3.4 TCP状态转移 TCP连接的任意一端在任一时刻都处于某种状态,当前状态可以通过netstat命令(见第17章)查看.本节我们要讨论的是TCP连接从建立到关闭的整个过程中通信两端状态的变化.图3-8是完整的状态转移图,它描绘了所有的TCP状态以及可能的状态转换. 图3-8中的粗虚线表示典型的服务器端连接的状态转移:粗实线表示典型的客户端连接的状态转移.CLOSED是一个假想的起始点,并不是一个实际的状态. 3.4.1 TCP状态转移总图 我们先讨论服务器的典型状态转移过程,此时我们说的连接

《Linux高性能服务器编程》——第3章 TCP协议详解 3.1 TCP服务的特点

第3章 TCP协议详解 TCP协议是TCP/IP协议族中另一个重要的协议.和IP协议相比,TCP协议更靠近应用层,因此在应用程序中具有更强的可操作性.一些重要的socket选项都和TCP协议相关. 本章从如下四方面来讨论TCP协议: 不过在详细讨论TCP协议之前,我们先简单介绍一下TCP服务的特点,以及它和UDP服务的区别. 3.1 TCP服务的特点 传输层协议主要有两个:TCP协议和UDP协议.TCP协议相对于UDP协议的特点是:面向连接.字节流和可靠传输. 使用TCP协议通信的双方必须先建立

《Linux高性能服务器编程》——3.2 TCP头部结构

3.2 TCP头部结构 TCP头部信息出现在每个TCP报文段中,用于指定通信的源端端口,目的端端口,管理TCP连接等,本节详细介绍TCP的头部结构,包括固定头部结构和头部选项. 3.2.1 TCP固定头部结构 TCP头部结构如图3-3所示,其中的诸多字段为管理TCP连接和控制数据流提供了足够的信息. 16位端口号(port number):告知主机该报文段是来自哪里(源端口)以及传给哪个上层协议或应用程序(目的端口)的.进行TCP通信时,客户端通常使用系统自动选择的临时端口号,而服务器则使用知名

《Linux高性能服务器编程》——1.7 socket和TCP/IP协议族的关系

1.7 socket和TCP/IP协议族的关系 前文提到,数据链路层.网络层.传输层协议是在内核中实现的.因此操作系统需要实现一组系统调用,使得应用程序能够访问这些协议提供的服务.实现这组系统调用的API(Application Programming Interface,应用程序编程接口)主要有两套:socket和XTI.XTI现在基本不再使用,本书仅讨论socket.图1-1显示了socket与TCP/IP协议族的关系. 由socket定义的这一组API提供如下两点功能:一是将应用程序数据从

《Linux高性能服务器编程》——3.7 TCP成块数据流

3.7 TCP成块数据流 下面考虑用FTP协议传输一个大文件.在ernest-laptop上启动一个vsftpd服务器程序(升级的.安全版的ftp服务器程序),并执行ftp命令登录该服务器上,然后在ftp命令提示符后输入get命令,从服务器下载一个几百兆的大文件.同时用tcpdump抓取这一个过程中ftp客户端和vsftpd服务器交换的TCP报文段.具体操作过程如下: $ sudo tcpdump –nt –i eth0 port 20 # vsftpd服务器程序使用端口号20 $ ftp 12