TCP/IP协议族

来源:互联网 发布:个人博客数据库 编辑:程序博客网 时间:2024/05/15 01:28

TCP/IP协议族,在网络中TCP/IP协议族是用的最多的协议族,现在互联网上也都是基于该协议族,它的另一个名字叫Internet协议族。这里我对TCP/IP协议进行综合的总结下。


1.概述


先说下TCP/IP的整体,TCP/IP的协议族中分为四个层次,如下图所示。后面的总结也是逐层向上来说的。


其中应用层和运输层是端到端的协议,(可以理解为进程端口到另一个进程端口的协议),而网络层是逐跳协议,它提供的是点到点的服务。这个先提一下,后面再回头来详细说明。


1.1 网络传输过程

网络之间传输的无非就是0101的信号流,也可以说是比特流。在这些0101的基础上面一层层地进行封装,构成了整个协议族。如下图所示的是以太网数据包的封装过程例子,主机A从应用程序的数据通过运输层封装了TCP首部(组成TCP报文段),到网络层又封装了IP首部(组成IP数据报),到链路层又封装了以太网首部(组成以太网帧),这样就构成了一个以太网帧(一段比特流),这个以太网帧通过我们的网络介质传输到达另一台主机B上,主机B拿到的是一个以太网帧,所以B也要遵循A封装时的各个协议,才能将这个帧也一层层解包成所需要的用户数据。这就是网络传输的简单过程。


通过上面的描述的过程或许会有疑惑,既然都是比特流,不干脆直接把用户数据发到另一台主机上不是更干脆,何必还要封装这么多层,多麻烦呀。

这里要说的是,在各层上的这些协议,各自的功能不同,需要结合他们一起工作,才能保证在复杂的网络环境中各数据被安全正确的送达:

1、链路层的协议就是要负责数据流在各个不同的网络环境中能正确传输,如主流的以太网,令牌网等。

2、网络层是负责数据流在网络节点之间的传输(主机、路由器等)

3、传输层就是负责主机端到端的正确传输(已经到进程)

4、应用层就是我们平时写的程序了,程序用调用的是socket APITCP/UDP的实现)

各层采用不同的协议,一起完成整个网络传输,如下图所示。


2.链路层


链路层是以帧作为传输包,链路层主要有三个作用:

1、发送接收IP数据报

2、发送接收ARP请求和应答

3、发送接收RARP请求和应答


2.1 两种帧格式

在链路层最常使用的有两种帧格式:以太网帧、IEEE 802

两种帧格式的对比如下图所示。他们都采用48bit6字节)的目的地址和源地址(也有16bit的),也就是常说的MAC物理地址。尾部的CRC字段则用于检验和。

以太网的帧和802标准的帧都有最小长度要求,因为802格式用了更多的字节来标识处理其他问题,所以802.3数据部分至少38字节,而以太网至少46字节。这个帧格式大概知道即可,更多的细节就不过多说明。



2.2 环回接口

环回接口允许同一台主机上的程序之间进行TCP/IP通信,在通信中基本都会遇到环回接口。

大多数是把IP地址127.0.0.1分配给这个接口,命名为localhost。大多数的传输实现中,给环回地址的数据包还是经过传输层和网络层,但不经过链路层,离开网络层后又返回给自己。

可以把环回接口看做是网络层下面的另一个链路层。


2.3 MTU

每个网络环境不一样,所以不同的网络帧格式对长度的限制不同,这个数据帧的最大传输单元叫MTU。下图是常见的几种MTU


IP层传输的数据报比MTU还要大的时候,就需要进行分片了,后面会讲到分片的细节。


2.4 ARP和RARP

ARP协议全称是地址解析协议,它的作用就是通过目标设备的IP地址,查询目标设备的MAC地址。一般是主机发送ARP请求,接收返回消息中获取目标IP地址的MAC地址,存入缓存供通信使用。

ARP攻击就是通过伪造IP地址和MAC地址实现ARP欺骗,如果MAC地址被伪造成一个不存在的地址,就会导致网络不通。或伪造成黑客主机的地址,导致信息被拦截,中间人攻击等。

RARP是反向地址转换协议,与ARP解析相反,通过MAC来查询IP地址。


3.网络层


要知道所有的TCPUDPICMPIGMP数据都以IP数据报格式进行传输,可见IP协议在TCP/IP协议族中的重要性。

IP协议是不可靠的,无连接的。简单地说就是IP协议不保证数据能正确抵达目的地,每个数据之间是无关联的,不是按发送顺序接收的。


3.1 IP首部(一般20字节,除非有选项字段):

·首部中,目前的协议版本号是4,因此也叫IPv4

·首部长度是指占32bit字的数目,包括选项;

·TOS包括3bit优先权子字段(已被忽略)、4bitTOS子字段和1bit未用位,其中4bit位分别代表:最小时延、最大吞吐量、最高可靠性、最小费用;

·总长度是整个IP数据报的长度,单位是字节;

·位标识字段唯一标识主机发送的每一份数据报;

·位标志和位片偏移在下面分片时来讨论;

·TTL,设置了生存时间段,每经过一个路由就减1,当到0时数据报就丢弃;

·协议(ICMPIGMPUDPTCP);

·首部检验和是根据首部计算的结果,用于抵达目的地后验证。


3.2 IP路由选择

在复杂的网络中,数据报从一台主机到另一台主机,需要经过许多个路由器,通过路由器的转发来到达目的地。而IP路由选择就是选择下一站路由的机制。

IP层在内存中有一个路由表,存储路径信息。当要转发一份数据报时就搜索该表一次,根据数据报信息和搜索结果,最终决定转发到下一站路由器或是主机,或者抛弃返回“主机不可达”的错误(ICMP)。


3.3 IP分片

IP层收到要发送的IP数据报时,通过选路对比对应接口的MTU与数据报长度,如果数据报太长,则需要进行分片。注意这里分片后到达“下一站”就进行重新组装,而不是到最终目的主机才组装。

分片和组装都是在IP层进行的,对于TCPUDP等运输层协议都是透明的


在上面说的IP首部中,第二行的网络字节序中:

·位标识字段在数据报被分片时,每个片都共用该值来标识同一个数据报;

·位标志字段中,其中一个比特表示“更多的片”:0表示“最后一片”,1表示后面还有片。另一个比特称作“不分片”位:1表示不分片;

·位片偏移字段是该片偏移原始数据报开始处的位置

而且数据报被分片后,总长度值要改成该片的长度值。分片后每一片是一个分组。


IP层没有重传机制,所以只要丢失一个分片,就需要重传整个数据报,因此我们要尽量避免分片。需要注意的是运输层首部(UDP首部,TCP首部)只在第一个分片中。


4.传输层


4.1.UDP

UDP是面向数据报的协议,所以它是不可靠的,不能保证数据安全到达。


UDP首部

UDP首部如下图所示

·IP层会根据IP首部中协议字段分配给TCPUDP,因此TCP端口号和UDP端口号是互相独立的;

·UDP长度指UDP首部+数据的字节长度;

·UDP检验和是根据首部(UDP伪首部+UDP首部)加上数据计算出来的,用于验证端到端的发送是否正确抵达;



UDP通信中,发送端发给接收端,接收端不会有任何确认信息返回,所以发送端是不知道接收端是否收到,也就是UDP的不可靠性。

在以太网中,帧最大长度是1500字节(MTU),假定IP首部20字节,UDP首部8字节,这样留给的就是1472字节。当UDP数据报大于这个数时就需要进行分片了。

在理论上IP数据报的最大长度是65535字节,除去20字节IP首部和8字节UDP首部,UDP数据报最大为65507。不过具体的长度限制还是要看具体的socket API实现了。

在许多UDP应用程序中,数据被限制为512字节或更小。


UDP服务器端

UDP服务器端,经常同时接收来发多个客户端的请求,这时这些请求将由UDP自动排队,而且输出队列是FIFO(先进先出)的。

UDP通信都是绑定地址的,它还可以限制远端地址,指定哪些端口接收哪些远端地址。UDP服务器可以创建三类地址绑定,如下图:


匹配顺序也是表中从上到下判断哪些端点接收优先。

UDP不像TCP那样需要建立连接,一次只发送一个数据报,因此效率上高很多,在很多应用程序中都有使用,如DNSTFTPBOOTPSNMP等。


4.2.TCP

TCP提供面向连接的、可靠的服务。因此,TCP的通信前必须先建立一个TCP连接,以及通信结束后断开也是要两边确认。

TCP仅是两方通信,因此广播和多播是不能用于TCP


TCP首部

TCP首部如果不计选项字段,通常是20字节。

·和UDP一样,TCP首部也包含源端口号和目的端口号;

·序号是标识从发端向收端的数据字节流,可看作TCP用序号对每个字节进行计数,建立一个新连接时,第一个字节序号为连接初始序号加1SYN标志消耗了一个序号);

·确认序号是上次收到的数据字节序号加1ACK1时确认序号才有效);

·URG:紧急指针;

·ACK:确认序号有效(一旦一个连接建立起来,ACK总是被设置为1);

·PSH:接收方应尽快将这个报文段交给应用层;

·RST:重新连接;

·SYN:同步序号,用来发起一个连接;

·FIN:发端完成发送;

·窗口大小用于控制流量,单位为字节数;

·检验和包括了首部和数据(强制性:发端计算存储,收端验证);

·URG1时,紧急指针表示一个偏移量,用于发端向收端发送紧急数据;

·常见的一个可选字段是最长报文大小(MSS),表示本端能接收的最大长度报文段,只出现在SYN报文段中。


TCP是全双工服务,两个方向都能独立进行传输。每个方向上的序号保持顺序。

一个IP地址和一个端口号称为一个插口(socket),所以一个socket可唯一确定每个TCP的一端。



三次握手和四次挥手

TCP在通信前需要先建立连接,通信结束后需要断开连接。连接的建立和终止的通信过程如下图所示,注意这7个报文段都只包含首部,没有任何数据。

其中1~3行是建立连接的三次握手:

1S表示SYN标志;后面跟着序号:隐含的结尾序号(数据字节数)win 4096表示发端的窗口大小;<mss 1024>表示最大报文长度。

2ack后面跟着的是确认序号。


上面的报文分别对应下图的时间过程:

三次握手:

1、客户端发送SYN段到服务端,包含初始序号(ISN)——报文段1

2、服务端发回SYN段作为应答,包含服务器的初始序号,和对报文段1ack确认序号(客户端ISN+1)——报文段2

3、客户端返回ack确认报文段(服务端ISN+1)——报文段3

因为TCP是全双工的,所以两端必须单独地进行关闭,所以需要四次挥手。


四次挥手:

通信两端都可以发起终止连接。

1、主机A应用程序关闭,发出FIN报文段到主机B,序号值为之前加1——报文段4

2、主机B收到这个FIN,返回一个ACK,确认序号为FIN的序号加1,这和连接的赋值方式一致——报文段5

3、这时主机B应用程序关闭,发给主机A一个FIN——报文段6

4、主机A收到FIN后再返回一个ACK给主机B——报文段7

需要注意的是各端的应用层进行关闭,才会发送FIN包。


首先来看下TCP的状态变迁图,下图展示了TCP的连接中涉及到的所有状态。


不管是客户端还是服务器端,进入ESTABLISHED状态表示连接建立,离开ESTABLISHED状态表示连接要关闭了。有11个状态名和netstat命令中显示的状态相对应。


下图是连接建立和终止所对应的状态图。

其中注意到客户端最后变迁到TIME_WAIT状态(也称为2MSL状态),该状态作用是防止最后的ACK确认报文未送达需要重传的。在TIME_WAIT状态下,该端口仍然被占用,不能被程序重新启动来使用,等待时间是MSL的两倍,主要看各系统的socket API的实现,目前的系统在30~4分钟都有。


UDP中,数据报到达目的端口时,该端口没在使用,将返回一个ICMP,而TCP是返回一个复位报文段。


同时打开

两个应用程序同时彼此执行主动打开的情况成为同时打开,虽然可能性很小,但也会发生的。这时候建立连接的过程如下图,一个同时打开的连接需要4个报文段。



同时关闭

同时关闭和过程和同时打开类似,两边同时主动关闭,如下图



服务器端TCP

大多数TCP服务器进程是并发的。一个新的请求到达服务器,服务器接受后调用一个新进程来处理这个客户的请求,之前的进程仍然是LISTEN状态等待新的客户连接。如下图所示。


服务端会有一个连接队列,存放已被TCP接受的连接(已完成三次握手),但还未被应用层使用。该队列长度称为积压值,范围在0~5之间,这个积压值是连接已被TCP接受而等待应用层的最大数,对系统允许的最大连接数,客户数不影响。

也就是说当连接在三次握手之后,应用层才会知道这个连接的存在。当队列满了,客户端的主动打开服务端并不会受理SYN,也不会返回RST作为应答,最终导致超时(第一次握手都不成功)。


TCP的数据流

TCP中的数据流有两种:交互数据流、成块数据流

1、交互数据流:

交互数据大多数实现只发送一个字节,如Rlogin,也有像Telnet发送一行数据。

Rlogin程序就是采用这种数据流,下图是Rlogin在客户端发出“date\n”时的通信过程。

为了减少报文数量,确认与回显可以一同发回,这称为经受时延的确认:

通常TCP在接收到数据时并不立即发送ACK,相反,他推迟发送,以便与相同方向上的数据一起发送。大多数的时延为200ms,系统内核有个200ms的定时器来定时检查通知。每200ms如果还没有需要发送的数据,这时才发ACK


像上面说到的,如果在广域网中太多这样的小分组存在,会导致网络拥塞的。Nagle算法就是为了解决这种情况:一个TCP连接上最多只能有一个未被确认的未完成分组,在该分组确认到达前不能发送其他分组。Nagle算法可以减少通信中的小报文数量。

2、成块数据流

还有一种流量控制方法是用了滑动窗口协议,该协议允许发送方在停止并等待确认前可以连续发送多个分组,加速数据的传输。

过程简单点说就是发送方一次发送多个分组,接收方一次对多个分组进行确认。

接收方是通过一个窗口来进行确认哪些数据已经确认,哪些未被确认,以及可用的缓存大小(发送方可以发送的最大字节)。下图展示了滑动窗口,这些数字就是接收端的缓存字节,窗口左边的是收到的数据并且已确认,窗口左部分是收到的数据但未确认,右部分是可用的窗口,也就是当前发送方可以发送的最大字节(在确认ACK中会标明)。随着收到的好确认的越来越多,窗口向右移动。

滑动窗口的大小通常socket API允许设置发送缓存和接收缓存的大小,接收缓存大小就是这个窗口的大小。不同系统有不同的默认值,204816384都有。

值得一提的是在传输文件等大的数据时,两个缓存到16384会有比较大的吞吐量。


为了避免一开始发送多个报文导致在广域网中出现拥塞,使用“慢启动”的方式。在发送方有一个拥塞窗口,每收到一个ACK拥塞窗口就加1,然后发送的报文数是拥塞窗口和通告窗口中较小值。这样就会导致一开始的时候发送一个、两个...再慢慢变多。拥塞窗口控制发送方的流量,通告窗口控制接收端的流量。

TCP的超时与重传

TCP通过确认包来保证数据的可靠传输,但是数据包和确认包都有可能会丢失,TCP在发送端发送时设置一个定时器,当定时器溢出时还没收到确认,它就重传该数据。

经过12次重传后仍然无法到达,则放弃并发送一个复位报文。

常用的TCP应用有TelnetRloginFTPSMTP等。


0 0
原创粉丝点击