TCP交互数据流

1. 交互式输入

首先来观察在一个rlogin连接上键入一个交互命令时所产生的数据流。许多TCP/IP的初学者很吃惊地发现通常每一个交互按键都会产生一个数据分组,也就是说 每次从客户传到服务器的是一个字节的按键(而不是每次一行!) 。而且rlogin需要远程系统(服务器)回显我们(客户)键入的字符。这样就会产生4个报文段:

1)来自客户的交互按键

2)来自服务器的按键确认

3)来自服务器的按键回显

4)来自客户的按键回显确认

图1表示了这个数据流:

rlogin-tcp-sequences.png

然而,一般可以将报文段2和3进行合并: 按键确认与按键回显一起发送 。

图2显示的是键入5个字符date\n时的数据流(没有显示连接建立的过程,并且去掉了所有的服务类型输出。BSD/386通过设置一个rlogin连接的TOS来获得最小时延)

rlogin-tcp-dump.png

1)与字符d有关的

        第1行:客户发送字符d到服务器

        第2行:该字符的确认及回显(同时返回)

        第3行:回显字符的确认(ACK)

第4~6行:与字符a有关的

第7~9行:与字符t有关的

第10~12行:与字符e有关

注意: 第3-4、6-7、9-10和12-13之间半秒的时间差是键入两个字符之间欸拿的时延。

第13~15行:从客户发送到服务器的是一个字符\n,而回显的则是两个字符

        客户端发送到服务器的是:按下RETURN键后产生的UNIX系统中的换行符

        服务器发送给客户端的是:回车和换行字符( CR/LF ),它们的作用是将光标回移到左边并移动到下一行

第16行:来自服务器的date命令的输出(即对应的日期展示)

        这30个字节由28个字符与最后的CR/LF组成,如图所示:

第18行:服务器发往客户的7个字符

        服务器主机上的客户提示符: svr4 %

第19行:客户端确认了这7个字符

请注意:TCP是怎样进行确认的

第1行以序号0发送数据字节,第2行通过将确认序号设为1,也就是 最后成功收到的字节的序号加1,来对其进行确认 ,也就是所谓的 下一个期望数据的序号

第2行中服务器还向客户发送了一序号为1的数据,客户在第3行中通过设置确认序号为2来对该数据进行确认

 

2. 经受时延的确认

图3表示了图2中数据交换的时间系列(在该时间系列中,去掉了所有的窗口通告,并增加了一个记号来表明正在传输何种数据):

rlogin-tcp-late-ack-sequences.png

把从bsdi发送到srv4的7个ACK标记为 经受时延的ACK 。通常TCP在接收到数据时并不立即发送ACK;相反,它推迟发送,以便将ACK与需要沿该方向发送的数据一起发送(有时称这种现象为数据捎带ACK)。绝大多数实现采用的时延为200ms,也就是说,TCP将以最大200ms的时延等待是否有数据一起发送

如果观察bsdi接收到数据和发送ACK之间的时间差,就会发现它们似乎是随机的:123.5、65.6、109.0、132.2、42.0、140.3和195.8ms。相反,观察到发送ACK的实际时间(从0开始)为:139.9、539.3、940.1、1339.9、1739.9、1940.1和2140.1ms(在图中用星号标出)。这些时间之间的差则是200ms的整数倍,这里所发生的情况是因为 TCP使用了一个200ms的定时器,该定时器以相对于内核引导的200ms固定时间溢出 。由于将要确认的数据是随机到达的(在时刻16.4,474.3,831.1等),TCP在内核的200ms定时器的下一次溢出时得到通知。这有可能是将来1~200ms中的任何一刻

如果观察svr4为产生所收到的每个字符的回显所使用的时间,则这些时间分别为16.5、16.3、16.5、16.4和17.3ms。由于这个时间小于200ms,因此我们在另一端从来没有观察到一个经受时延的ACK。在经受时延的定时器溢出前总是有数据需要发送(如果有一个约为16ms等待时间越过了内核的200ms时钟滴答的边界,则仍可以看到一个经受时延的ACK。在本例中我们一个也没有看到)

当为检测超时而使用500ms的TCP定时器时,会看到同样的情况。这两个200ms和500ms的定时器都在相对于内核引导的时间处溢出。 不论TCP何时设置一个定时器,该定时器都可能在将来1~200ms和1~500ms的任一处溢出。

注意:RFC声明TCP需要实现一个经受时延的ACK,但时延必须小于500ms

3. Nagle算法

一个Rlogin连接上客户一般每次发送一个字节到服务器,这就产生了一些41字节长的分组:20字节的IP首部、20字节的TCP首部和1个字节的数据。在局域网上,这些小分组(被称为微小分组),通常不会引起麻烦,因为局域网一般不会出现拥塞。但在广域网上,这些小分组则会增加拥塞出现的可能。一种简单和好的方法就是采用RFC 896中所建议的Nagle算法

Nagle算法要求一个TCP连接上最多只能有一个未被确认的未完成的小分组,在该分组的确认到达之前不能发送其他的小分组 。相反, TCP收集这些少量的分组,并在确认到来时以一个分组的方式发出去。

在图3中可以看到,在以太网上一个字节被发送、确认和回显的平均往返时间约为16ms。为了产生比这个速度更快的数据,我们每秒键入的字符必须多于60个。这表明在局域网环境下两个主机之间发送数据时很少使用这个算法

但是,当往返时间增加时,如通过一个广域网,情况就会发生变化。看一下在主机slip和主机vangogh.cs.berkeley.edu之间的rlogin连接工作的情况。为了从我们的网络中出去,需要使用两个SLIP链路和Internet。我们希望获得更长的往返时间。图4显示了当在客户端快速键入字符(像一个快速打字员一样)时一些数据流的时间系列:

rlogin-wan-sequences.png

1)从slip到vangogh不存在经受时延的ACK。这是因为在时延定时器溢出之前总是有数据等待发送

2)从左到右待发数据的长度是不同的,分别为:1、1、2、1、2、2、3、1和3个字节。这是因为客户只有收到前一个数据的确认后才发送已经收集的数据。通过使用Nagle算法,为发送16个字节的数据客户只需要使用9个报文段,而不再是16个;

3)报文段14和15看起来似乎是与Nagle算法相违背的,但我们需要通过检查序号来观察其中的真相。因为确认序号是54,因此报文段14是报文段12中确认的应答。但客户在发送该报文段之前,接收到了来自服务器的报文段13,报文段15中包含了对序号为56的报文段13的确认。因此即使我们看到从客户到服务器有两个连续返回的报文段, 客户也是遵守了Nagle算法的

4)在图中可以看到存在一个经受时延的ACK,但该ACK是从服务器到客户的(报文段12),因为它不包含任何数据,因此我们可以假定这是经受时延的ACK。服务器当时一定非常忙,因此无法在服务器的定时器溢出前及时处理所收到的字符

5)最后两个报文段中数据的数量以及相应的序号。客户发送3个字节的数据(18,19和20),然后服务器确认这3个字节(最后的报文段中的ACK 21),但是只返回了一个字节(标号为59)。这是因为当服务器的TCP一旦正确收到这3个字节的数据,就会返回对该数据的确认,但只有当rlogin服务器发送回显数据时,它才能够发送这些数据的回显。这表明 TCP可以在应用读取并处理数据前发送所接收数据的确认。TCP确认仅仅表明TCP已经正确接收了数据 。最后一个报文段的窗口大小为8189而非8192, 表明服务器进程尚未读取这三个收到的数据

4. Nagle算法关闭

有时也需要关闭Nagle算法。一个典型的例子是X窗口系统服务器:小消息(鼠标移动)必须无时延地发送,以便为进行某种操作的交互用户提供实时的反馈

这里将举另外一个更容易说明的例子:在一个交互注册过程中键入终端的一个特殊功能键。这个功能键通常可以产生多个字符序列,经常从ASCII码的转义(escape)字符开始。如果TCP每次得到一个字符,它很可能会发送序列中的第一个字符(ASCII码的ESC),然后缓存其他字符并等待对该字符的确认。但当服务器接收到该字符后,它并不发送确认,而是继续等待接收序列中的其他字符。这就会经常触发服务器的经受时延的确认算法,表示剩下的字符没有在200ms内发送。对交互用户而言,这将产生明显的时延

注意:

1)socket API 用户可以使用TCP_NODELAY选项来关闭Nagle算法;

2)RFC声明TCP必须实现Nagle算法,但必须为应用提供一种方法来关闭该算法在某个连接上的执行;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WebSocket是一种使用HTTP协议进行握手的协议,它能够在客户端和服务器之间建立持久的双向通信通道。一般情况下,客户端通过向服务器发送请求来获取数据,而服务器则根据请求返回相应的数据给客户端。然而,这种方式存在一定的延迟,尤其在需要实时更新数据的场景下不够高效。 使用WebSocket可以解决这个问题,它可以在客户端和服务器之间建立一条持久连接,使得服务器能够主动推送数据给客户端,实现实时的数据流拉取。通过WebSocket,客户端和服务器可以随时发送消息给对方,而不需要经过请求-响应的过程。 在使用WebSocket拉取实时数据流时,客户端会首先与服务器建立连接,建立连接后,客户端可以通过发送特定的消息给服务器来请求获取实时数据。服务器会根据客户端的请求,将最新的数据实时推送给客户端。客户端可以监听服务器发送的消息,一旦有新的数据到来,就可以进行相应的处理和展示。 WebSocket的实时数据流拉取具有以下优点: 1. 实时性高:服务器可以主动推送实时数据给客户端,无需等待客户端发起请求。 2. 低延迟:由于WebSocket使用的是TCP连接,而不是HTTP的请求-响应模式,因此数据传输效率更高,延迟更低。 3. 双向通信:WebSocket支持客户端和服务器之间的双向通信,可以实现真正的实时交互。 4. 节省带宽:WebSocket使用持久连接,不需要像HTTP那样每次请求都带上请求头等信息,节省了带宽资源。 5. 兼容性好:WebSocket协议的支持度较高,各种浏览器和平台均可以使用。 总之,通过WebSocket进行实时数据流拉取,可以提升数据传输效率、降低延迟,并实现双向通信,适用于需要实时更新数据的场景,如股票行情、即时聊天等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值