TCP、UDP、IP 协议分析
所谓协议就是双方进行数据传输的一种格式。早期互联网使用的是NCP协议,这种协议本身有很多缺陷,为了改进缺陷,大牛们弄出了TCP/IP协议。现在几乎所有的操作系统都实现了TCP/IP协议栈。
TCP/IP 协议栈主要分为四层:应用层、传输层、网络层、数据链路层,每一层都有对应的协议
在Linux操作系统中,当我们想发送数据的时候,我们只需要在上层准备好数据,在发送数据的过程中,经过各层的时候会加上各层协议的头部信息。下面让我们来看一看每一层添加的协议头的具体内容。
一、TCP协议
TCP协议是面向连接、保证高可靠性(数据无丢失、数据无失序、数据无错误、数据无重复到达)传输层协议。
1.TCP头分析
先来分析一下TCP头的格式以及每一个字段的含义:
(1)端口号
我们知道,网络实现的是不同主机的进程间通信。在一个操作系统中,有很多进程,当数据到来时要提交给哪个进程进行处理呢?这就需要用到端口号。在TCP头中,有源端口号(Source Port)和目标端口号(Destination Port)。源端口号标识了发送主机的进程,目标端口号标识接受方主机的进程。源端口和目标端口是用16位表示的,可以推算计算机的端口号有2^16个
(2)***:表示本报文段所发送数据的第一个字节的编号。在TCP连接中所传送的字节流的每一个字节都会按顺序编号。由于***由32位表示,所以每2^32个字节,就会出现***回绕,再次从0 开始
(3)确认号:表示接收方期望收到发送方下一个报文段的第一个字节数据的编号。也就是告诉发送发:我希望你(指发送方)下次发送的数据的第一个字节数据的编号是这个确认号
(4)数据偏移:表示TCP报文段的首部长度,共4位,由于TCP首部包含一个长度可变的选项部分,需要指定这个TCP报文段到底有多长。它指出TCP 报文段的数据起始处距离TCP 报文段的起始处有多远。该字段的单位是32位(即4个字节为计算单位),4位二进制最大表示15,所以数据偏移也就是TCP首部最大60字节
(5)保留位:暂时未使用
(6)标志:在TCP首部中有6个比特位。它们中的多个可同时设为1
URG 紧急指针(urgent pointer)有效
ACK 确认序号有效
PSH 指示接收方应该尽快将这个报文段交给应用层而不用等待缓冲区装满
RST 一般表示断开一个连接
SYN 同步序号用来发起一个连接
FIN 发送端完成发送任务(即断开连接)
(7)窗口大小;表示源方法最多能接受的字节数
(8)校验和:提供额外的可靠性
(9)紧急指针:只有当URG标志位值为1时才有效
(10)选项部分:常见选项:最大报文长度,窗口扩大,时间戳等
二、重点详解
1、TCP建立连接时的三次握手
所谓三次握手就是说在建立一个TCP连接时,需要客户端和服务器端总共发送三个包以确认连接的建立。
(1)第一次握手:客户端将发送一个将SYN标志位设为1,在客户端***为x的数据包给服务器端,并进入SYN-SENT 状态,等待服务器端的确认
(2)第二次握手:服务器端在收到数据包后,有数据包上SYN=1知道客户端请求连接,服务器端将会发送一个 SYN和ACK 标志位值均为1且在服务器端序号为y的数据包,ack=1表示希望客户端下次发送第x+1个包,间接说明服务器收到了第x个数据包。客户端进入SYN-REVD状态。
(3)第三次握手:客户端在收到服务器发送的确认包后,检查ACK是否为1 ,ack是否为x+1,如果正确,将发送一个ACK标志位值为1,ack=y+1的数据包给服务器端,服务器检查ack是否为y+1,ACK是否为1,如果正确将完成三次握手,客户端和服务器端进入ESTABLISHED状态,随后就可以传输数据了。
注:
(A)不要将确认序号ack与标志位中的ACK搞混
(B)确认方ack=发起方的***+1 ,两端配对
2、.四次挥手断开连接
所谓四次挥手即终止TCP连接,就是断开一个TCP连接时,需要客户端和服务器端总共发送四个包来确认断开。
(1)第一次挥手:客户端一个标志位为1的数据包,用来关闭客户端到服务器端的数据传送,客户端进入FIN_WAIT_1状态。
(2)第二次挥手:服务器端在收到一个标志FIN=1的数据包后,会发送一个标志ACK=1的数据包给客户端,,服务器进入CLOSE_WAIT状态,客户端在收到数据包之后进入。FIN_WAIT_2 状态
(3)第三次挥手:在第二次挥手之后,服务器端会接着给客户端传输没有传完的数据,在数据传输结束之后,服务器端会给客户端发送一个标志位FIN=1的数据包,用来关闭服务器端到客户端的数据传送,随后服务器进入LAST_ACK状态。
(4)第四次挥手:客户端在收到FIN之后,进入TIME_WAIT状态,接着会发送一个ACK给服务器,服务器会进去CLOSED状态,完成第四次挥手。
注:服务器不能长时间处于CLOSED状态,在一次连接结束之后,服务器会快速进入LIATEN状态,等待下一个服务连接。
3、TCP在建立连接和断开连接过程中涉及到的几种状态:
CLOSED 没有任何连接状态。
LISTEN侦听状态,等待来自远方TCP端口的连接请求。
SYN-SENT在发送连接请求后,等待对方确认。
SYN-RECEIVED在收到和发送一个连接请求后,等待对方确认。
ESTABLISHED代表传输连接建立,双方进入数据传送状态。
FIN-WAIT-1主动关闭,主机已发送关闭连接请求,等待对方确认。
FIN-WAIT-2主动关闭,主机已收到对方关闭传输连接确认,等待对方发送关闭传输连接请求。
TIME-WAIT完成双向传输连接关闭,等待所有分组消失。
CLOSE-WAIT被动关闭,收到对方发来的关闭连接请求,并已确认
LAST-ACK被动关闭,等待最后一个关闭传输连接确认,并等待所有分组消失。
CLOSING双方同时尝试关闭传输连接,等待对方确认。
4、有限状态机
客户端先发送一个FIN给服务端,自己进入了FIN_WAIT_1状态,这时等待接收服务端的报文,该报文会有三种可能:
只有服务端的ACK
只有服务端的FIN
基于服务端的ACK,又有FIN
(1)、只收到服务器的ACK,客户端会进入FIN_WAIT_2状态,后续当收到服务端的FIN时,回应发送一个ACK,会进入到TIME_WAIT状态,这个状态会持续2MSL(TCP报文段在网络中的最大生存时间, RFC 1122标准的建议值是2min).客户端等待2MSL,是为了当最后一个ACK丢失时,可以再发送一次。因为服务端在等待超时后会再发送一个FIN给客户端,进而客户端知道ACK已丢失。
(2)、只有服务端的FIN时,回应一个ACK给服务端,进入CLOSING状态,然后接收到服务端的ACK时,进入TIME_WAIT状态。
(3)、同时收到服务端的ACK和FIN,直接进入TIME_WAIT状态。
三、UDP协议
UDP也是传输层的协议,它是无连接,不保证可靠的传输层协议。它的协议头部比较简单,如下:
这里的端口号跟TCP的端口号是一样的意义,就不解释了
Length占了两个字节,用来表示UDP的长度。
Checksum:校验和。
四、IP协议
IP协议是工作在网络层的协议,所有的TCP、UDP、ICMP、IGMP数据以数据包个格式传输。它的特点如下:
不可靠:它不能保证IP数据包能成功到达目的地,IP仅提供最好的传输服务,无数据恢复功能。
无连接:独立处理数据包,也就是说IP数据包可以不按发送顺序接收。如果一信源向相同的信宿发送两个连续的数据报(先是 A,然后是B),每个数据报都是独立地进行路由选择,可能选择不同的路线,因此B可能在A到达之前先到达。
(1)版本 占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位,用来获得更好的服务。这个字段在旧标准中叫做服务类型,但实际上一直没有被使用过。1998年IETF把这个字段改名为区分服务DS(Differentiated Services)。只有在使用区分服务时,这个字段才起作用。
(4)总长度 总长度指首部和数据之和的长度,单位为字节。总长度字段为16位,因此数据报的最大长度为216-1=65535字节。
在IP层下面的每一种数据链路层都有自己的帧格式,其中包括帧格式中的数据字段的最大长度,这称为最大传送单元MTU(Maximum Transfer Unit)。当一个数据报封装成链路层的帧时,此数据报的总长度(即首部加上数据部分)一定不能超过下面的数据链路层的MTU值。
(5)标识(identification) 占16位。IP软件在存储器中维持一个计数器,每产生一个数据报,计数器就加1,并将此值赋给标识字段。但这个“标识”并不是序号,因为IP是无连接服务,数据报不存在按序接收的问题。当数据报由于长度超过网络的MTU而必须分片时,这个标识字段的值就被复制到所有的数据报的标识字段中。相同的标识字段的值使分片后的各数据报片最后能正确地重装成为原来的数据报。
(6)标志(flag) 占3位,但目前只有2位有意义。
A、标志字段中的最低位记为MF(More Fragment)。MF=1即表示后面“还有分片”的数据报。MF=0表示这已是若干数据报片中的最后一个
B、标志字段中间的一位记为DF(Don’t Fragment),意思是“不能分片”。只有当DF=0时才允许分片。
(7)片偏移 占13位。片偏移指出:较长的分组在分片后,某片在原分组中的相对位置。也就是说,相对用户数据字段的起点,该片从何处开始。片偏移以8个字节为偏移单位。这就是说,每个分片的长度一定是8字节(64位)的整数倍。
(8)生存时间 占8位,生存时间字段常用的的英文缩写是TTL(Time To Live),表明是数据报在网络中的寿命。由发出数据报的源点设置这个字段。其目的是防止无法交付的数据报无限制地在因特网中兜圈子,因而白白消耗网络资源。最初的设计是以秒作为TTL的单位。每经过一个路由器时,就把TTL减去数据报在路由器消耗掉的一段时间。若数据报在路由器消耗的时间小于1秒,就把TTL值减1。当TTL值为0时,就丢弃这个数据报。
(9)协议 占8位,协议字段指出此数据报携带的数据是使用何种协议,以便使目的主机的IP层知道应将数据部分上交给哪个处理过程。
(10)首部检验和 占16位。这个字段只检验数据报的首部,但不包括数据部分。这是因为数据报每经过一个路由器,路由器都要重新计算一下首部检验和(一些字段,如生存时间、标志、片偏移等都可能发生变化)。不检验数据部分可减少计算的工作量。
(11)源IP地址 占32位。
(12)目的IP地址 占32位
五、附注
关于三次握手与四次挥手通常都会有典型的面试题,
(1)三次握手是什么或者流程?四次握手呢?答案前面分析就是。
(2)为什么建立连接是三次握手,而关闭连接却是四次挥手呢?
这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方也未必全部数据都发送给对方了,所以己方可以立即close,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送。
转载于:https://blog.51cto.com/13136984/1962109