TCP<=>Transmission Control Protocol<=>传输控制协议,和UDP<=>UserDatagram Protocol<=>用户数据报协议一道位于OSI(Open System Interconnect) Reference Model<=>开放系统互联参考模型的Layer4<=>传输层。
下面就针对传输层的两个重要协议TCP和UDP作一对比性的介绍。
UDP提供无连接的、不可靠的数据报服务;而TCP恰恰相反,提供面向连接的、可靠的字节流服务。UDP适用于多媒体服务中实时数据的传输;而TCP则适用于对传输质量要求较高的场合。另外需要注意的是,TCP会有较大的时延,不适合对实时性要求较高的场合。
面向连接意味着两个使用TCP的应用(Server和Client)在交互数据之前,必须先建立一个TCP的连接。
(1)一个TCP的连接由四元组(Src_ip, Src_port,Dst_ip, Dst_port)唯一确定;
(2)TCP协议规定通信双方需通过3次握手(3-way HandShake)方能连接一个TCP连接。
TCP协议通过如下几种方式保证传输的可靠性(数据无误、无失序、无丢失、无重复到达):
(1)超时重传机制:源端发送一个TCP Segment后,会启动一个超时定时器,等待对端的ACK;若在定时时间内未收到ACK,则会重新发送这个Segment;
(2)ACK机制:TCP中通信的双方接收到彼此发送的报文后,均要向对方发送一个ACK报文;需要注意的是,这个ACK报文,可能并不会立即发送,而是推迟一小段时间;
(3)TCP Header中CheckSum字段:该字段对TCP Header和Data进行校验,目的是检测在传输过程中,报文是否发生变化;若接收端收到的CheckSum有问题,则会丢弃该报文并不发送ACK;
(4)TCP会对接收到的报文进行重新排序;
(5)TCP会丢弃重复的报文;
(6)流量控制:TCP连接的每一方均有固定大小的缓冲空间;TCP接收端只能允许发送端发送接收缓冲区所能接纳的数据,这样可以防止缓冲区的溢出。
(1)源端口号:
SourcePort,16位,它(连同源主机IP地址)标识源主机的一个应用进程。
(2)目的端口号:
Destination Port,16位,它(连同目的主机IP地址)标识目的主机的一个应用进程。
四元组<=>(src_ip+src_port+dst_ip+dst_port)可以唯一确定一个TCP连接。
(3)顺序号:
Sequence Number,32位,用于对发送的字节流进行计数,表示发送端报文段中第一个数据字节的顺序号。
序号是32bit的无符号数,序号到达232-1后又从0开始。当建立一个新的连接时, SYN标志为1,顺序号字段表示通信各方在该连接中的初始顺序号ISN( Initial Sequence Number)。
(4)确认号:
Acknowledgementnumber,32位,包含发送确认的一端所期望收到的下一个顺序号。因此,确认序号应当是上次已成功收到数据字节顺序号加1。
①Sequence number标识包的序号,TCP的接收端会根据Sequence number对packet进行重新排序,解决网络packet乱序的问题; ②Acknowledgement number确认收到,用于解决丢包的问题。 |
(5)TCP报头长度:
4位,给出报头中32bit字的数目,它实际上指明数据从哪里开始。需要这个值是因为任选字段的长度是可变的。这个字段占4bit,因此TCP最多有60字节的首部。然而,没有任选字段,正常的长度是20字节。
(6)保留位:
6位,保留给将来使用,目前必须置为 0。
(7)控制位:
在TCP报头中有6个标志比特(controlflag),表示TCP Packet的类型,主要用于操控TCP的StateMachine。需要注意的是,多个controlflag可以同时设置为1。
控制位 |
全称 |
16进制值 |
描述信息 |
URG |
urgent |
0x20 |
紧急指针有效位 |
ACK |
acknowledgement |
0x10 |
确认序列号有效 |
PSH |
push |
0x08 |
接收方应尽快将该packet上交应用层处理 |
RST |
reset |
0x04 |
连接复位 |
SYN |
synchronize |
0x02 |
同步序列号,发起一个新连接 |
FIN |
finish |
0x01 |
发送端完成发送任务 |
①URG:为1表示紧急指针(urgentpointer)有效,为0则忽略紧急指针值。
②ACK:为1表示确认号有效,为0表示忽略确认号字段。
③PSH:为1表示是带有PUSH标志的数据,指示接收方应该尽快将这个报文段交给应用层而不用等待缓冲区装满。
④RST:用于复位由于主机崩溃或其他原因而出现错误的连接。它还可以用于拒绝非法的报文段和拒绝连接请求。一般情况下,如果收到一个RST为1的报文,那么一定发生了某些问题。
⑤SYN:为1表示连接请求,用于发起一个连接,并同步顺序号。TCP通信双方发送数据第一个字节序号为ISN+1,因为SYN标志会消耗一个顺序号。
⑥FIN:用于释放连接,为1表示发送方已经没有数据发送了,即关闭本方数据流。
(8)窗口大小:
Windowsize,16位,因而窗口大小最大为65535;TCP的流量控制就是由连接的每一端通过声明窗口大小实现的。
(9)校验和:
Checksumof entire TCP segment,16位,针对entireTCP segment(header+data);这是一个强制性的字段,由发送端计算和存储,并由接收端进行验证。
(10)紧急指针:
Urgentpointer,16位,是一个正的偏移量,和顺序号字段中的值相加表示紧急数据最后一个字节的序号。TCP的紧急方式是发送端向另一端发送紧急数据的一种方式。
(11)选项:
最常见的可选字段是最长报文大小,又称为MSS(Maximum Segment Size)。每个连接方通常都在通信的第一个报文段(为建立连接而设置SYN标志的那个段)中指明这个选项,它指明本端所能接收的最大长度的报文段。
PS:①IP Header 20 字节;②TCPHeader 20字节;③MACHeader 14字节:包含目的MAC地址、源MAC地址、协议类型三个字段。
(12)数据:
TCP报文段中的数据部分是可选的。在一个连接建立和一个连接终止时,双方交换的报文段就仅有TCP首部。
参考资料:http://www.tcpipguide.com/free/t_TCPOperationalOverviewandtheTCPFiniteStateMachineF-2.htm#Figure_210
3.1.1 FSM简介
FSM<=>FiniteState Machine<=>有限状态机<=>A tool used by many computerscientists to describe the operation of a protocol or algorithm is the finitestate machine. It describes the different actions taken by a piece of softwareover time by defining a finite number of operating states, events that can cause transitions between states, andactions taken in responseto events.
FSM是被计算机科学家用来描述一个协议或算法复杂操作的工具。FSM有如下4个基本要素:
①State:概括了一个协议在某一时间点的状态(环境+现状);
②Transition:各个State之间的转化;
③Event:导致Transition的事件;
④Action:在Transition之前对Event的response。
3.1.2 TCP FSM相关的control flag
首先,我们来重温一下TCPPacket Header的Controlflag字段中与TCPFSM相关的flags:
①SYN:Asynchronize message, used to initiate and establish a connection. It is sonamed since one of its functions is to synchronizes sequence numbers betweendevices.
同步TCP segment,用来初始化并建立一个连接,SYN如此命名是因为它的功能之一是在同步sequence number。
②FIN:Afinish message, which is a TCP segment with the FIN bit set, indicating that adevice wants to terminate the connection.
FIN 比特位置1的TCP segment,表明一方想要终止TCP连接。
③ACK:Anacknowledgment, indicating receipt of a message such as a SYN or a FIN.
确认segment,对接收到的SYN/FINsegment的确认。
3.1.3 TCP FSM之States
(1)CLOSED:
CLOSED状态是TCP连接建立之前的默认状态,在TCP标准中将这种状态称之为“fictional(虚构的)”。
①Passiveopen<=>server端被动打开,会设置管理连接的TCB(transimission control block),接着就会转化到LISTEN状态;
②Activeopen<=>client端主动打开,同样设置TCB,且会发送SYN来发起连接,然后进入SYN-SENT状态。
(2)LISTEN:
LISTEN<=>server端等待监听client端的SYNsegment。
在server端接收到client端发送的SYNsegment之后就会发送SYN+ACKsegment;然后server端进入SYN-RECEIVED状态。
(3)SYN-SENT:
SYN-SENT<=>client端发送过SYNsegment,等待server端回复匹配的SYNsegment。
①如果server端仅仅发送SYNsegment,那么client会回复ACKsegment,并进入SYN-RECEIVED状态,等待server端回复ACKsegment;
②如果server端回复ACKsegment并发送ACKsegment,那么client端会回复ACKsegment,并进入ESTABLISHED状态。
(4)SYN-RECEIVED:
SYN-RECEIVED<=>任一端(server/client)接受过对端发送的SYNsegment,也发送过自己的SYNsegment,就会进入这个状态,等待对端对自己的SYNsegment做出确认(acknowledgement)完成连接的建立。
(5)ESTABLISHED:
ESTABLISHED<=>一个开放的TCP连接的稳定状态(steadystate),在该状态下,通信双方可以自由地交换数据。
①如果其中一方要终止TCP连接,则会发送FINsegment,然后进入FIN-WAIT-1状态。
②如果接收到partner发送的FINsegment,会对FINsegment进行确认并进入CLOSE-WAIT状态。
(6)CLOSE-WAIT:
CLOSE-WAIT<=>接收到partner发送的关闭请求(closerequest<=>FIN segment),会等待本机应用程序关闭,并发送一个匹配的请求(即FINsegment),然后进入LAST-ACK状态。
(7)LAST-ACK:
LAST-ACK<=>接收到对端发送的FIN,进行了ACK,也发送了自己的FIN,就会进入这个状态,等待对端进行ACK。
在接收到对端的ACK后,本机就会直接进入CLOSED状态。
(8)FIN-WAIT1:
FIN-WAIT1<=>在该状态下的主机发送了自己的FIN,正在等待对端发送ACK或者FIN。
若接收到ACK,就会进入FIN-WAIT-2状态;
若接收到FIN,就会发送ACK,并进入CLOSING状态。
(9)FIN-WAIT2:
FIN-WAIT-2<=>在这种状态下主机已经发送了自己的FIN并接收到了ACK,正在等待对端发送FIN。
若接收到对端发送的FIN,就会发送ACK,并进入到TIME-WAIT状态。
(10)CLOSING:
CLOSING<=>在这种状态主机接收到了对端的FIN,并发送了ACK,但还接收到对端对自己FIN的ACK。
若接收到了对端的ACK,就会进入TIME-WAIT状态。
(11)TIME-WAIT:
TIME-WAIT<=>在这种状态,双方均已发送了FIN,并接收到ACK;等待一段时间之后,双方就会进入CLOSED状态。
参考资料:http://www.tcpipguide.com/free/t_TCPConnectionEstablishmentProcessTheThreeWayHandsh-3.htm
Thenormal process of establishing a connection between a TCP client and serverinvolves three steps:
(1)theclient sends a SYN message;
(2)theserver sends a message that combines an ACK for the client’s SYN and containsthe server’s SYN;
(3)andthen the client sends an ACK for the server’s SYN. This is called the TCPthree-way handshake.
从tcpdump包中看TCP连接的建立:
参考资料:http://www.tcpipguide.com/free/t_TCPConnectionTermination-4.htm
(1)相关参数在文件系统中的存放位置:/proc/sys/net/ipv4/tcp_*和/etc/sysctl.conf;
(2)TCP相关参数的含义参见:
https://www.frozentux.net/ipsysctl-tutorial/ipsysctl-tutorial.html#TCPVARIABLES
(3)可以通过执行命令:sysctl-a命令查看/proc/sys/net/ipv4/目录下所有参数文件的值;
若要查看指定参数的值,可以执行命令:sysctl[parameter_name];
或者直接cat相应文件即可,eg:cat/proc/sys/net/ipv4/tcp_keepalive_probes
(1)直接修改/proc/sys/net/ipv4/目录下参数文件的值:
Eg:$ echo10 > /proc/sys/net/ipv4/tcp_keepalive_probes
但是这种方法会在系统重启后失效。
(2)执行命令:$sysctl -w [parameter_name]=[value]:
Eg:sysctl-w net.ipv4.tcp_keepalive_probes=10
(3)修改/etc/sysctl.conf文件,将相应的配置项写入该文件中:
Eg:net.ipv4.tcp_keepalive_probes=10
原理:系统启动后,会从/etc/sysctl.conf文件中读取相应的配置项并初始化/proc/sys/net/ipv4/目录下对应的文件内容。
注意:修改过此文件后,系统必须重启,修改才能生效;若不想重启,那么执行命令:sysctl-p /etc/sysctl.conf即可。
RTT<=>RoundTrip Time<=>往返时间<=>代表从发送一个TCPpacket到接收对端回复的ACK之间的时间。
RTT由3部分组成:
(1)链路的传播时间(propagationdelay);
(2)末端系统的处理时间;
(3)路由器缓存中的排队和处理时间(queuingdelay)。
注意:
前两个部分的值对于一个TCP连接来说相对固定;而路由器缓存中的排队和处理时间会随着整个网络拥塞成都的变化而变化。
故而RTT值在一定程度上反映了网络的拥塞程度。
RTT的测量方法之一:
RTT= 当前时间- packet中Timestamp选项的回显时间
Timestamp选项表示的是packet发出去的时间。
RTO<=>RetransmissionTimeOut<=>重传超时时间<=>代表发送一个TCPpacket后,如果迟迟未收到ACK,多久后会重传这个packet;也就是重传定时器的定时时间。
RFC2988中对RTO的介绍如下:
The Transmission Control Protocol (TCP) uses a retransmission timer to ensure data delivery in the absence of any feedback from the remote data receiver. The duration of this timer is referred to as RTO (retransmission timeout). |
在/kernel/include/net/tcp.h中定义了关于TCP报文的属性值,其中定义RTO的最大/最小值如下:
#defineTCP_RTO_MAX ((unsigned)(120*HZ))
#defineTCP_RTO_MIN ((unsigned)(HZ/5))
TCP在packet传输的过程中会对RTT进行采样(即对发送packet和其ACK的时间差进行测量),进而根据RTT值动态更新RTO。
PS:HZ?
HZ是Kernel中的一个宏,在asm/param.h中定义:
(1)HZ值与平台有关,表示系统1S内产生的时钟中断次数,即系统时钟中断的产生频率;
(2)jiffies是Kernel中的一个全局变量,表示系统自开机到当前产生的时钟中断的次数;
(3)所以jiffies/HZ即表示了系统自开机到当前所经过的时间(单位:S)。
(1)http://www.tcpipguide.com/free/t_toc.htm
(2)http://elf8848.iteye.com/blog/2089414
(3)http://blog.csdn.net/apn172/article/details/8034240
占4位,指IP协议的版本。通信双方使用的IP协议版本必须一致。目前广泛使用的IP协议版本号为4(即IPv4)。关于IPv6,目前还处于草案阶段。
(2)首部长度
占4位,可表示的最大十进制数值是15。
请注意,这个字段所表示数的单位是32位字长(1个32位字长是4字节),因此,当IP的首部长度为1111时(即十进制的15),首部长度就达到60字节。
当IP分组的首部长度不是4字节的整数倍时,必须利用最后的填充字段加以填充。因此数据部分永远在4字节的整数倍开始,这样在实现IP协议时较为方便。
首部长度限制为60字节的缺点是有时可能不够用。但这样做是希望用户尽量减少开销。最常用的首部长度就是20字节(即首部长度为0101),这时不使用任何选项。
(3)区分服务
占8位,用来获得更好的服务。这个字段在旧标准中叫做服务类型(TOS, Type of Service),但实际上一直没有被使用过。1998年IETF把这个字段改名为区分服务DS(Differentiated Services)。只有在使用区分服务时,这个字段才起作用。
(4)总长度
总长度指整个IP数据包的长度,单位为字节。总长度字段为16位,因此数据报的最大长度为216-1=65535字节。
在IP层下面的每一种数据链路层都有自己的帧格式,其中包括帧格式中的数据字段的最大长度,这称为最大传送单元MTU(Maximum Transfer Unit)。当一个数据报封装成链路层的帧时,此数据报的总长度(即首部加上数据部分)一定不能超过下面的数据链路层的MTU值。
(5)标识(identification)
占16位。IP软件在存储器中维持一个计数器,每产生一个数据报,计数器就加1,并将此值赋给标识字段。但这个“标识”并不是序号,因为IP是无连接服务,数据报不存在按序接收的问题。当数据报由于长度超过网络的MTU而必须分片时,这个标识字段的值就被复制到所有的数据报的标识字段中。相同的标识字段的值使分片后的各数据报片最后能正确地重装成为原来的数据报。
标志(flag)
占3位,但目前只有2位有意义。
●标志字段中的最低位记为MF(More Fragment)。MF=1即表示后面“还有分片”的数据报。MF=0表示这已是若干数据报片中的最后一个。
●标志字段中间的一位记为DF(Don’t Fragment),意思是“不能分片”。只有当DF=0时才允许分片。
(6)片偏移
占13位。片偏移指出:较长的分组在分片后,某片在原分组中的相对位置。也就是说,相对用户数据字段的起点,该片从何处开始。
片偏移以8个字节为偏移单位。这就是说,每个分片的长度一定是8字节(64位)的整数倍。
(7)生存时间TTL(Time To Live)
占8位,TTL字段表明了数据报在网络中的寿命,即指定了数据报可以经过的最多路由器数。
TTL的初始值由源主机设置。其目的是防止无法交付的数据报无限制地在因特网中兜圈子,白白耗费网络资源。
数据报每经过一个路由器,它的TTL值就减1;当该字段值为0时,数据报就会被丢弃,并发送ICMP报文通知源主机。
(8)协议
占8位,协议字段指出此数据报携带的数据是使用何种协议,以便使目的主机的IP层知道应将数据部分上交给哪个处理过程。
(9)首部检验和
占16位。这个字段只检验数据报的首部,但不包括数据部分。这是因为数据报每经过一个路由器,路由器都要重新计算一下首部检验和(一些字段,如生存时间、标志、片偏移等都可能发生变化)。不检验数据部分可减少计算的工作量。
(11)源地址 占32位。
(12)目的地址 占32位。
(1)TCPHeader:
(2)IPHeader:
(3)UDPHeader:
(4)ICMPHeader: