TCP协议--带外数据和超时重传

来源:互联网 发布:英语对话软件 编辑:程序博客网 时间:2024/05/21 12:49

《Linux高性能服务器编程》阅读笔记:

1. 带外数据

  有些传输层协议具有带外(Out Of Band, OOB)数据的概念,用于迅速告知对方本端发生的重要事件。因此带外数据比普通数据(也称为带内数据)有更高的优先级,不论发送缓冲区中是否有排队等待发送的普通数据,带外数据总是被立即发送。带外数据的传输可以使用一条独立的传输层连接,也可以映射到传输层普通数据的连接中。但是在实际应用中,带外数据的使用少见,已知的仅有telnet、ftp等远程非活跃程序。

  UDP没有实现带外数据传输,TCP也没有真正意义上的带外数据。但是TCP利用其头部中的紧急指针标志(URG)和紧急指针两个字段,为应用程序提供了一种紧急方式。TCP紧急方式是利用传输普通数据的连接来传输紧急数据的,这种紧急数据的含义类似于带外数据。

  TCP模块接收带外数据的默认方式:TCP在只有在接收到紧急指针标志的前提下才检查紧急指针,然后根据紧急指针指向的位置确定带外数据的位置,并将其读取到一个特殊的缓存中,该缓存只有1字节,称为带外缓存。若上层应用程序没有及时将带外数据从带外缓冲区中读出,则后续的带外数据(如果有的话)将覆盖它。

  除了默认方式外,如果程序员给TCP连接设置了SO_OOBINLINE选项,则带外数据将和普通数据一样被TCP模块读取存放在TCP接收缓冲区中。此时应用程序像读取普通数据一样读取带外数据。在这种情况下,区分带外数据/普通数据的方法依旧是利用可以指出带外数据位置的紧急指针。socket()编程接口也提供了系统调用来识别带外数据。

2. 超时重传

  在TCP协议–TCP头部一文中,讲到TCP”是面向连接、字节流和可靠传输”的传输层协议。TCP服务的报文段能够超时重传,是可靠传输具体体现之一。为此,TCP模块为每个TCP报文段都维护了一个重传定时器,该定时器在TCP报文段第一次被发送时启动。若超时时间内未收到接收方的应答,TCP模块将重传TCP报文段并重置定时器。下次重传的超时时间如何选择,以及最多执行多少次重传,这就是TCP的重传策略

  下面以tcpdump工具,抓取超时重传的数据包:

telnet服务端: ubuntu14.04 192.168.1.16telnet客户端: ubuntu11.04 192.168.1.36

  在ubuntu14.04机器启动iperf服务器程序(iperf是第一个测量网络状况的工具,-s选项表示将其作为服务器运行。iperf默认监听5001端口,并丢弃该端口上接收到的所有数据),然后在ubuntu11.04机器执行telnet命令登录该服务器程序。接着在客户端发送数据(“1234”)给服务端,然后断开服务端网线后再次从客户端发送数据服务端(“12”),同时在客户端利用tcpdump抓取过程的TCP报文:

$ iperf -s                 #在服务端$ sudo tcpdump -n -i eth0 port 5001    $ telnet 192.168.1.16      #在客户端

  tcpdump抓取的数据包:

listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes1. 00:16:13.422087 IP 192.168.1.36.58474 > 192.168.1.16.5001: Flags [S], seq 2637883451, win 14600, options [mss 1460,sackOK,TS val 369022 ecr 0,nop,wscale 6], length 02. 00:16:13.534750 IP 192.168.1.16.5001 > 192.168.1.36.58474: Flags [S.], seq 1175616253, ack 2637883452, win 28960, options [mss 1460,sackOK,TS val 711376 ecr 369022,nop,wscale 7], length 03. 00:16:13.534776 IP 192.168.1.36.58474 > 192.168.1.16.5001: Flags [.], ack 1, win 229, options [nop,nop,TS val 369050 ecr 711376], length 04. 00:16:28.173726 IP 192.168.1.36.58474 > 192.168.1.16.5001: Flags [P.], seq 1:7, ack 1, win 229, options [nop,nop,TS val 372710 ecr 711376], length 65. 00:16:28.262645 IP 192.168.1.16.5001 > 192.168.1.36.58474: Flags [.], ack 7, win 227, options [nop,nop,TS val 715058 ecr 372710], length 06. 00:17:11.993524 IP 192.168.1.36.58474 > 192.168.1.16.5001: Flags [P.], seq 7:11, ack 1, win 229, options [nop,nop,TS val 383665 ecr 715058], length 47. 00:17:12.325492 IP 192.168.1.36.58474 > 192.168.1.16.5001: Flags [P.], seq 7:11, ack 1, win 229, options [nop,nop,TS val 383748 ecr 715058], length 48. 00:17:12.989454 IP 192.168.1.36.58474 > 192.168.1.16.5001: Flags [P.], seq 7:11, ack 1, win 229, options [nop,nop,TS val 383914 ecr 715058], length 49. 00:17:14.321511 IP 192.168.1.36.58474 > 192.168.1.16.5001: Flags [P.], seq 7:11, ack 1, win 229, options [nop,nop,TS val 384247 ecr 715058], length 410. 00:17:16.982161 IP 192.168.1.36.58474 > 192.168.1.16.5001: Flags [P.], seq 7:11, ack 1, win 229, options [nop,nop,TS val 384912 ecr 715058], length 411. 00:19:51.274626 IP 192.168.1.36.58474 > 192.168.1.16.5001: Flags [P.], seq 7:11, ack 1, win 229, options [nop,nop,TS val 423484 ecr 715058], length 412. 00:19:51.275984 IP 192.168.1.16.5001 > 192.168.1.36.58474: Flags [R], seq 1175616254, win 0, length 0

  (1) 报文段1~3是三次握手建立连接的过程
  (2) 报文段4~5是客户端发送数据”1234”(length长度为6,包括回车、换行两个字符)及服务端确认的过程
  (3) 报文段6是客户端第一次发送数据”12”的过程,此时因为服务端的网线被断开,所以客户端无法收到TCP报文段6的确认报文段,此后,客户端对报文段6执行了5次重传,即报文段7~11
  (4) 报文段12是复位报文段,证明了客户端访问的地址不存在

  Linux系统中有两个重要的内核参数与TCP超时重传相关:

/proc/sys/net/ipv4/tcp_retries1 指定最少执行的重传次数/proc/sys/net/ipv4/tcp_retries2 指定链接放弃前TCP最多可以执行的重传次数

这里写图片描述

  虽然超时会导致TCP报文段重传,但TCP报文段的重传可以发生在超时之前,即快速重传