(转)计算机网络基础知识总结

原文:https://i.cnblogs.com/EditPosts.aspx?opt=1

          http://blog.csdn.net/scenlyf/article/details/52127296

         http://blog.csdn.net/shaozhenged/article/details/52047277

说到网络相关知识,首先先说说计算机网络体系结构中两种最为重要的参考模型,OSI参考模型和TCP/IP参考模型。

1、OSI参考模型:

       OSI(Open System Interconnect),即开放式系统互联。一般都称为OSI参考模型,是ISO(国际标准化组织)组织在1985年研究的网络互联模型。该体系结构标准定义了网络互连的七层框架(物理层、数据链路层、网络层、传输层、会话层、表示层和应用层),即ISO开放系统互连参考模型。第一层到第三层属于OSI参考模型的低三层,负责创建网络通信连接的链路;第四层到第七层为OSI参考模型的高四层,具体负责端到端的数据通信。在这一框架下进一步详细规定了每一层的功能,以实现开放系统环境中的互连性、互操作性和应用的可移植性。 

OSI参考模型中,对等层协议之间交换的信息单元统称为协议数据单元(PDU,Protocol Data Unit)。   
传输层——数据段(Segment)   网络层——分组(数据包)(Packet)   数据链路层——数据帧(Frame)   物理层——比特(Bit)

2、TCP/IP参考模型:

        TCP/IP参考模型是计算机网络的祖父ARPANET和其后继的因特网使用的参考模型。ARPANET是由美国国防部DoD(U.S.Department of Defense)赞助的研究网络。逐渐地它通过租用的电话线连结了数百所大学和政府部门。当无线网络和卫星出现以后,现有的协议在和它们相连的时候出现了问题,所以需要一种新的参考体系结构。这个体系结构在它的两个主要协议出现以后,被称为TCP/IP参考模型(TCP/IP reference model)。

       TCP/IP是一组协议的代名词,它还包括许多协议,组成了TCP/IP协议簇。TCP/IP协议簇分为四层(从下到上分为第一、二、三、四层的),IP位于协议簇的第二层(对应OSI的第三层:网络层),TCP位于协议簇的第三层(对应OSI的第四层:传输层)。TCP/IP通讯协议采用了4层的层级结构,每一层都呼叫它的下一层所提供的网络来完成自己的需求。这4层分别为: 

应用层:应用程序间沟通的层,如简单电子邮件传输(SMTP)、文件传输协议(FTP)、网络远程访问协议(Telnet)等。 
传输层:在此层中,它提供了节点间的数据传送服务,如传输控制协议(TCP)、用户数据报协议(UDP)等,TCP和UDP给数据包加入传输数据并把它传输到下一层中,这一层负责传送数据,并且确定数据已被送达并接收。 
互连网络层:负责提供基本的数据封包传送功能,让每一块数据包都能够到达目的主机(但不检查是否被正确接收),如网际协议(IP)。 
网络接口层:对实际的网络媒体的管理,定义如何使用实际网络(如Ethernet、Serial Line等)来传送数据。

 

 

       

 

       OSI七层模型结构的协议体系结构结构完整,概念明确,但其只能算是理想的一种体系结构,在实际应用中显得发杂,定义的层数越多,实现的难度也就随之越大,所以TCP/IP的四层模型结构成了至今被大量运用的网络体系的模型结构,但这并不意味着OSI就被搁置一旁甚至弃而不用。

3、两种模型结构的比较:

共同点:

1)、OSI参考模型和TCP/IP参考模型都采用了层次结构的概念。

2)、都能够提供面向连接和无连接两种通信服务机制。

不同点:

1)、OSI采用的七层模型,而TCP/IP是四层结构。

2)、TCP/IP参考模型的网络接口层实际上并没有真正的定义,只是一些概念性的描述。而OSI参考模型不仅分了两层,而且每一层的功能都很详尽,            甚至在数据链路层又分出一个介质访问子层,专门解决局域网的共享介质问题。

3)、OSI模型是在协议开发前设计的,具有通用性。TCP/IP是先有协议集然后建立模型,不适用于非TCP/IP网络。

4)、OSI参考模型与TCP/IP参考模型的传输层功能基本相似,都是负责为用户提供真正的端对端的通信服务,也对高层屏蔽了底层网络的实现细节。            所不同的是TCP/IP参考模型的传输层是建立在网络互联层基础之上的,而网络互联层只提供无连接的网络服务,所以面向连接的功能完全在TCP          协议中实现,当然TCP/IP的传输层还提供无连接的服务,如UDP;相反OSI参考模型的传输层是建立在网络层基础之上的,网络层既提供面向连          接的服务,又提供无连接的服务,但传输层只提供面向连接的服务。

5)、OSI参考模型的抽象能力高,适合与描述各种网络;而TCP/IP是先有了协议,才制定TCP/IP模型的。

6)、OSI参考模型的概念划分清晰,但过于复杂;而TCP/IP参考模型在服务、接口和协议的 区别上不清楚,功能描述和实现细节混在一起。

7)、TCP/IP参考模型的网络接口层并不是真正的一层;OSI参考模型的缺点是层次过多,划分意义不大但增加了复杂性。

8)、OSI参考模型虽然被看好,由于技术不成熟,实现困难;相反,TCP/IP参考模型虽然有许多不尽人意的地方,但还是比较成功的。

 

       关于TCP/IP的四层模型结构,也可以是五层结构,即在最底层加上了物理层,因为物理层注重的是信号的传递以及具有某些电机特性,所以严格的来讲,应该将其加上,放在网络接口层的下层位置。

 

 

4、关于各层间的作用(基于TCP/IP):

1)、物理层:

        指的是电信号传递方式,比如现在以太网通用的网线(双绞线)、早期以太网采用的同轴电缆(现在主要用于有线电视)、光纤等都属于物理层的概念。 物理层的能力决定了最大传输速率、传输距离、抗干扰性等。集线器(Hub)是工作在物理层的网络设备,用于双绞线的连接和信号中继(将已衰减的信号再次放大使之传得更远)。

 

2)、链路层:

        链路层有以太网、令牌环网等标准。链路层负责网卡设备的驱动、帧同步(就是说从网线上检测到什么信号算作新帧的开始)、冲突检测(如果检测到冲突就自动重发)、 数据差错校验等工作。交换机是工作在链路层的网络设备,可以在不同的链路层网络之间转发数据帧(比如十兆以太网和百兆以太网之间、以太网和令牌环网之间),由于不同链路层的帧格式不同,交换机要将进来的数据包拆掉链路层首部重新封装之后再转发。

       网络层的IP协议是构成Internet的基础。Internet上的主机通过IP地址来标识,Internet上有大量路由器负责根据IP地址选择合适的路径转发数据包,数据包从Internet上的源主机到目的主机往往要经过十多个路由器。路由器是工作在第三层的网络设备,同时兼有交换机的功能,可以在不同的链路层接口之间转发数据包。因此路由器需要将进来的数据包拆掉网络层和链路层两层首部并重新封装。IP 协议不保证传输的可靠性,数据包在传输过程中可能丢失,可靠性可以在上层协议或应用程序中提供支持。

 

 

 

 

3)、网络层:

        负责点到点的传输(这里的“点”指主机或路由器),而传输层负责端到端 (end-to-end)的传输(这里的“端”指源主机和目的主机)。

       网络层的主要作用就是路由和寻址,主要接触到的是IP协议即为IP地址

       Layer3网络层:对应设备有路由器

路由器的作用:

广播、组播控制

对数据做寻址、选择到达目的的网络的最佳路径

流量管理

连接广域网(WAN)

IP地址概念的说明:

根据地址的概念,来举例介绍网络号和主机号的概念,以及路由寻址和路由的概念。

 

4)、传输层:

       该层定义了两个重要的协议,即传输控制协议(TCP)或用户数据报协议(UDP)。TCP是一种面向连接的、可靠的协议。就像打电话,双方拿起电话互通身份之后就建立了连接,然后说话就行了,这边说的话那边保证听得到,并且是按说话的顺序听到的,说完话挂机断开连接。也就是说TCP传输的双方需要首先建立连接,之后由TCP协议保证数据收发的可靠性,丢失的数据包自动重发,上层应用程序收到的总是可靠的数据流,通讯之后关闭连接。UDP协议不面向连接,也不保证可靠性,有点像寄信,写好信放到邮筒里,既不能保证信件在邮递过程中不会丢失,也不能保证信件是按顺序寄到目的地的。使用UDP协议的应用程序需要自己完成丢包重发、消息排序等工作。

 

5)、应用层:

         为用户提供各种所需的服务。比如:FTP,DNS,Telnet,SMTP等。

 

 

5、TCP/IP协议栈与数据封装

       TCP/IP网络协议栈分为应用层(Application)、传输层(Transport)、网络层(Network)和链路层(Link)四层。

      关于两台计算机通过TCP/IP协议通讯的过程(局域网的两个主机可以通信)见下图:

      只有应用层由用户提供,传输层及其以下的机制由内核提供。应用程序对通讯数据的含义进行解释,而传输层及其以下的机制处理通讯的细节,将数据从一台计算机通过一定的路径发送到另一台计算机。

      应用层数据通过协议栈发到网络上时,每层协议都要加上一个数据首部(header),称为封装(Encapsulation),如下图所示:

 

 

                                                                           TCP/IP数据包的封装

过程:

       应用层将数据通过TCP/IP协议栈逐层向下传递,其下的每层接到来自上层的数据时,根据每层的协议都要在其数据的前端添加首部信息进行封装。不同的协议层对数据包有不同的称谓,在传输层叫做段(segment),在网络层叫做数据报(datagram),在链路层叫做帧(frame)。在经过链路层时,数据封装成帧后发给物理层的传输介质上,到达目标主机后,每层协议再逐层剥掉其首部,最后递交给目标主机应用层,进行应用程序处理,数据与源主机发送的数据一致。

       每层都将数据包分为:有效头部信息和有效载荷(数据)。对于有效数据称之为“有效载荷”,添加的部分称其为“报头”。下层收到来自上层交付的数据时,对于下层来说并不关心其具体内容,因为站在当前层的角度来看,此时已添加上层报头信息的数据整个都被视为有效载荷,当前层要做的只是继续封装该数据,即添加自己的报头。而解包的过程亦是如此,每层只负责剥离自己能识别的报头信息。任何数据报中的报头信息必须包含"上层协议",即要把当前的有效载荷交付给上层的谁。

 

 

 

上图适应两台计算机在同一网段的情况,如果是不同网段,从源主机到目标主机间的数据传输则须经过一个或多个路由器,以实现数据的跨网络传输。

 

 

 

        路由器是工作在第三层的网络设备,同时兼有交换机的功能,可以在不同的链路层接口之间转发数据包。因此路由器需要将进来的数据包拆掉网络层和链路层两层首部并重新封装。在此过程中,仍认为在同一层进行了网络连接。

       目的主机收到数据包后,如何经过各层协议栈最后到达应用程序呢?整个过程如下图所示

1、以太网驱动程序根据以太网首部中的“上层协议”字段确定该数据帧的有效载荷(指除去协议首部之外实际传输的数据)是IP、ARP还是RARP协议的数据报。

2、交给相应的协议处理。假如是IP数据报,IP协议再根据IP首部中的“上层协议”字段确定该数据报的有效载荷是TCP、UDP、ICMP还是IGMP ,然后交给相应的协议处理。假如是TCP段或UDP段,TCP或UDP协议再根据TCP首部或UDP首部的“端口号”字段确定应该将应用层数据交给哪个用户进程。

     IP 地址是标识网络中特定主机的地址,而端口号就是同一台主机上标识特定进程的地址,IP 地址和端口号合起来标识网络中唯一的进程。
注意:

       虽然IP、ARP和RARP数据报都需要以太网驱动程序来封装成帧,但是从功能上划分,ARP和RARP属于链路层,IP属于网络层。虽然ICMP、IGMP、TCP、UDP的数据都需要IP协议来封装成数据报,但是从功能上划分,ICMP、IGMP与IP同属于网络层,TCP和UDP属于传输层。

 

 

6、以太网帧格式

 

其中的源地址和目的地址是指网卡的硬件地址(也叫MAC地址),长度是48位(12个字节),是在网卡出厂时固化的。

 

帧协议类型字段有三种值,分别对应IP、ARP、RARP,而后是有效载荷的大小(数据长度)。帧末尾是CRC校验码,用于差错校验的。

帧协议其类型值分别为0800的IP协议,0806的ARP协议,0835的RARP协议。

用ifconfig命令看一下MAC地址,“HWaddr 00:1C:29:6E:00:8F”部分就是硬件地址。

     以太网帧中的数据长度规定最小46字节,最大1500字节,ARP和RARP数据包的长度不够46字节,要在后面补填充位。

     最大值1500称为以太网的最大传输单元(MTU),不同的网络类型有不同的MTU,如果一个数据包从以太网路由到拨号链路上,数据包长度大于拨号链路的MTU了,则需要对数据包进行分片(fragmentation)。ifconfig命令的输出中也有“MTU:1500”。注意,MTU这个概念指数据帧中有效载荷的最大长度,不包括帧首部的长度。

 

7、ARP协议

 

       概念:ARP协议原名为“地址解析协议”,是根据IP地址获取物理地址的一个TCP/IP协议。主机发送信息时将包含目标IP地址的ARP请求广播到网络上的所有主机,并接收返回消息,以此确定目标的物理地址。收到返回消息后将该IP地址和物理地址存入本机ARP缓存中并保留一定时间,下次请求时直接查询ARP缓存以节约资源。

       目的:在网络通讯时,源主机的应用程序知道目的主机的IP地址和端口号,却不知道目的主机的硬件地址,而数据包首先是被网卡接收到再去处理上层协议的,如果接收到的数据包的硬件地址与本机不符,则直接丢弃。因此在通讯前必须获得目的主机的硬件地址,ARP协议就起到这个作用。

       每台主机都维护一个ARP缓存表,可以用arp -a命令查看。缓存表中的表项有过期时间(一般为20分钟),如果20分钟内没有再次使用某个表项,则该表项失效,下次还要发ARP请求来获得目的主机的硬件地址。

      源MAC地址、目的MAC地址在以太网首部和ARP请求各出现一次,对于链路层为以太网的情况是多余的,但如果链路层是其它类型的网络则有可能是必要的。帧协议类型字段有三种值,分别对应IP、ARP、RARP。硬件类型指链路层网络类型,1为以太网。协议类型指要转换的地址类型,0x0800为IP地址。后面两个地址长度对于以太网地址和IP地址分别为6和4(字节),即0604。op字段:op字段为1表示ARP请求,op字段为2表示ARP应答。  

例如:A主机(源地址)向B主机(目的地址)进行ARP请求,A的MAC为:00:05:5d:61:58:a8;A的IP地址:c0 a8 00 37(192.168.0.55)。

          B的MAC为:00:05:5d:a1:b8:40;B的IP地址:c0 a8 00 02(192.168.0.2).

请求帧为 

以太网首部(14字节) ff ff ff ff ff 00 05 5d 61 58 a8 08 06         //广播地址的目标地址是全1。08 06:ARP帧

APR帧(28字节)     

00 01                          //硬件类型表示为以太网;硬件地址(MAC地址)长度为6,协议地址(IP地址)长度为4(0604)

08 0006 04 00 01 00 05 5d 61 58 a8 c0 a8 00 37    //协议类型0800表示为IP地址;op为0x0001表示请求;

00 00 00 00 00 00c0  a8 00 02   //此处目的以太网地址为全0,IP地址为B的。A主机ARP的目的就是获得B主机硬件地址(MAC地址/物理地址)。

填充位(18字节)

应答帧为:

以太网首部 (字节) 00 05 5d 61 58 a8 00 05 5d a1 b8 40 08 06

 

APR帧(28字节)     

 

00 01                      

08 00 06 04 00 02 00 05 5d a1 b8 40 c0 a8 00 02   //op为0x0002表示应答;

00 05 5d 61 58 a8 c0  a8 00 37  //目的以太网地址和IP地址为A的

填充位(18字节)

8、RARP协议

RARP协议

       原名为“反向地址解析协议”,允许局域网的物理机器从网关服务器的ARP表或者缓存上请求其IP地址。网络管理员在局域网网关路由器里创建一个表以映射物理地址(MAC)和与其对应的IP地址。当设置一台新的机器时,其RARP客户机程序需要向路由器上的 RARP 服务器请求相应的IP地址。假设在路由表中已经设置了一个记录,RARP 服务器将会返回 IP 地址给机器,此机器就会存储起来以便日后使用。

产生原因

     ARP(地址解析协议)是设备通过自己知道的IP地址来获得自己不知道的物理地址的协议。假如一个设备不知道它自己的IP地址,但是知道自己的物理地址,设备知道的只是网络接口卡上的物理地址时,又该怎么办呢? 为解决这种情况,就有了与ARP对应的RARP协议。

工作方式

      RARP以与ARP相反的方式工作。RARP发出要反向解析的物理地址并希望返回其对应的IP地址,应答包括由能够提供所需信息的RARP服务器发出的IP地址。虽然发送方发出的是广播信息,RARP规定只有RARP服务器能产生应答。许多网络指定多个RARP服务器,这样做既是为了平衡负载也是为了作为出现问题时的备份。

 

9、IP协议(重点)

       IP数据报的格式,见下图:

       IP数据报的首部长度和数据长度都是可变长的,但总是4字节的整数倍。对于IPv4 ,4位版本字段是4。4位首部长度的数值是以4字节为单位的,最小值为5,也就是首部长度最小是4x5=20字节, 也就是不带任何选项的IP首部,4位能表示的最大值是15,也就是首部长度最大是60字节。8位TOS字段有3个位用来指定IP数据报的优先级(目前已经废弃不用),还有4个位表示可选的服务类型(最小延迟、最大呑吐量、最大可靠性、最小成本),还有一个位总是0。 

       16位总长度是整个数据报(包括IP首部和IP层payload)的字节数。16位标识:每传一个IP数据报,16位的标识加1,可用于分片和重新组装数据报。

       3位标志和13位片偏移用于分片。

       TTL(Time to live)是这样用的:源主机为数据包设定一个生存时间,比如64,每过一个路由器就把该值减1,如果减到0就表示路由已经太长了仍然找不到目的主机的网络,就丢弃该包,因此这个生存时间的单位不是秒,而是跳(hop)。协议字段指示上层协议是TCP、UDP、ICMP还是IGMP。然后是校验和,只校验IP首部,数据的校验由更高层协议负责。IPv4的IP地址长度为32位。

下面主要进行说明IP分片和重组

3个标志位:

 

1)、最高位必须为0,该位必须复制到所有分组中。

2)、不分片位(no not fragment,DF位)。DF=0表示可以分片;DF=1表示接受主机对分组不能分片。如果长度超过MTU(最大传输单元)而又不可以分片的话,那么只能丢弃该组,并且用ICMP差错报文向源主机报告。

3)、分片位(More fragment,MF位)。该位表示是否是最后一个分片,MF=1表示接收的分组不是最后一片,否则表示是最后一片。

IP如何分片:

1)、检查DF标志位,检查是否允许分片。如果设置了该位,则数据报将被丢弃,并将一个ICMP错误返回给源主机。

2)、基于MTU,确定片长度,将数据长度分为若干部分。(除了最后的数据部分,所有新建的数据选项的长度必须是8个字节的整数倍。)

3)、每个数据部分被放入一个IP数据报,这些数的数据报的报头略微修改了原来的报文头。

4)、除了最后的数据报分片外,每个分片都设置了多个分片标志位。

5)、每个分片的偏移量字段设置为这个数据部分在原来的数据报所占的位置,这个位置相当于原来未分片的数据报的开头处。

6)、如果在原来的数据报中包括了选项,则选项类型字节的高位字节决定了这个信息是被复制到所有的分片数据段,还是只复制到了第一个数据报。

7)、设置新数据报的报文头字段及总长度字段。

8)、重新计算报文头部校验和。

IP的组装:

        为了高效第组装分片,用于保存分片的数据结构必须做到:

1)、快速定位属于某一数据报的一组分组。

2)、在属于某一数据报的一组分片中快速插入新的分片。

3)、有效地判断一个数据报的所有分片是否已经全部接收。

4)、具有组装超时机制,如果在重组完成之前定时器溢出,则删除该数据报的所有内容。

 

 

关于IP协议常见的问题:
1、为什么IP不是可靠连接的协议
     IP层没有超时和重传机制,没有连接握手协议。
2、IP数据报经过路由器都做了哪些改动
     IP没经过一个路由器,TTL数就会减一,如果最后TTL为0了,但是依然没有到达目的地,这个IP包将会被丢弃。这样做了目的是为了防止出现循环回路。并且最后一跳的路由器会发送一个ICMP不可达的数据包给源IP。
3、关于分片的问题
      IP数据包的长度为16,也就是说最大为65535个字节。但是我们知道数据链路层规定MTU最大传输单元为1500个字节。当IP数据包的大小超过了1500,IP数据包必须要进行分片处理。这还只是初始发送端的分片,在网络中如果某个路由器的MTU小于1500,那么还需要在路由器端做分片,这就给IP包的完整接收照成了很大的不确定性(我们知道数据包达到终点不一定是按照顺序的),因为万一某一个分片丢失,可能会造成真个IP重传,当然前提是高层协议支持重传。对于TCP协议,不存在分片的问题,因为TCP报头的选项字段有MSS字段,规定一个TCP包最大可传输的字节数,一般是1500-20-20=1460字节。也就是说到达IP封包的时候最大可承载数据只有1460个字节,这样就可以避免分片的问题。但是对于UDP这一类的协议,分片操作还是交给IP完成,虽然这样可以增加载荷的效率,但是稳定性会受到很大的影响。

 

 

IP地址与路由:

IP地址分为5类:(IPv4的IP地址长度为4字节,通常采用点分〸十进制表示法)

A类 0.0.0.0到127.255.255.255 

B类 128.0.0.0到191.255.255.255

C类 192.0.0.0到223.255.255.255
D类 224.0.0.0到239.255.255.255 

E类 240.0.0.0到247.255.255.255

       IP地址与子网掩码做与运算可以得到网络号,主机号从全0到全1就是子网的地址范围。

       127.*的IP地址用于本机环回(loop back)测试,通常是127.0.0.1。loopback是系统中一种特殊的网络设备,如果发送数据包的目的地址是环回地址或者与本机其它网络设备的IP地址相同,则数据包不会发送到网络介质上,而是通过环回设备再发回给上层协议和应用程序,主要用于测试。

一些不能用作主机IP 地址的特殊地址:

      目的地址为255.255.255.255 ,表示本网络内部广播,路由器不转发这样的广播数据包。

      主机号全为0的地址只表示网络而不能表示某个主机,如192.168.10.0(假设子网掩码 为255.255.255.0)。
      目的地址的主机号为全1,表示广播至某个网络的所有主机,例如目的地址192.168.10.255表示广播至192.168.10.0网络(假设子网掩码为255.255.255.0)。

        路由表:由很多路由条目组成,每个条目都指明去往某个网络的数据包应该经由哪个接口发送,其中最后一条是缺省路由条目。路由条目路由表中的一行,每个条目主要由目的网络地址、子网掩码、下一跳地址、发送接口四部分组成,如果要发送的数据包的目的网络地址匹配路由表中的某一行,就按规定的接口发送到下一跳地址。缺省路由条目路由表中的最后一行,主要由下一跳地址和发送接口两部分组成,当目的地址与路由表中其它行都不匹配时,就按缺省路由条目规定的接口发送到下一跳地址。

        路由是从寻找目标网络开始的,对于路由来说其找寻目标网络地址一般有三种可能:

        1、知道,但当前网段找不到(送至下一路由);2、不知道,也找不到。(送至默认网关);3、知道,也能在当前网段找到。

       路由如何确定要发送的网络号?

       IP数据报中存有目标IP地址,所以当路由获得该地址时,通过与子网掩码的“与”操作,便能得到一个网络号,将其与路由表中的目标地址(Destination)条目进行逐一比对,如果比对成功则通过该网络号对应的发送接口(Use Iface)发出;若未匹配到,则说明不在该局域网络,须将其从eth0的发送接口发出,将其送至默认网关处,再由其路由表决定下一跳的地址。

 

10、UDP协议

 

 

       UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。在OSI模型中,在第四层的传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。UDP协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似协议所掩盖,但是即使是在今天UDP仍然不失为一项非常实用和可行的网络传输层协议。

 

      UDP协议不面向连接,也不保证传输的可靠性。例如:发送端的UDP协议层只管把应用层传来的数据封装成段交给IP协议层就算完成任务了,如果因为网络故障该段无法发到对方,UDP协议层也不会给应用层返回任何错误信息。接收端的UDP协议层只管把收到的数据根据端口号交给相应的应用程序就算完成任务了,如果发送端发来多个数据包并且在网络上经过不同的路由,到达接收端时顺序已经错乱了,UDP协议层也不保证按发送时的顺序交给应用层。通常接收端的UDP协议层将收到的数据放在一个固定大小的缓冲区中等待应用程序来提取和处理,如果应用程序提取和处理的速度很慢,而发送端发送的速度很快,就会丢失数据包,UDP协议层并不报告这种错误。因此,使用UDP协议的应用程序必须考虑到这些可能的问题并实现适当的解决方案,例如等待应答、超时重发、为数据包编号、流量控制等。一般使用

UDP协议的应用程序实现都比较简单,只是发送一些对可靠性要求不高的消息,而不发送大量的数据。例如,基于UDP的TFTP协议一般只用 trivial ftp TCP FTP于传送小文件,而基于TCP的协议适用于各种文件的传输。

UDP协议的特点:UDP使用底层的互联网协议来传送报文,同IP一样提供不可靠的无连接数据包传输服务。它不提供报文到达确认、排序、及流量控制等功能。

 

11、TCP协议(重点)

                                                                                                 TCP段格式

 

       这里主要说一下六个标志位,URG、ACK、PSH、RST、SYN和FIN。

       SYN表示建立连接,FIN表示关闭连接;ACK表示响应;PSH表示有 DATA数据传输;RST表示连接重置;URG表示紧急指针字段有效。

       SYN、FIN、ACK位:其中ACK是可能与SYN,FIN等同时使用的,比如SYN和ACK可能同时为1,它表示的就是建立连接之后的响应。如果只是单个的一个SYN,它表示的只是建立连接。TCP的几次握手就是通过这样的ACK表现出来的。但SYN与FIN是不会同时为1的,因为前者表示的是建立连接,而后者表示的是断开连接。

        RST位:RST一般是在FIN之后才会出现为1的情况,表示的是连接重置。一般地,当出现FIN包或RST包时,我们便认为客户端与服务器端断开了连接;而当出现SYN和SYN+ACK包时,我们认为客户端与服务器建立了一个连接。

        PSH位(Push):PSH为1的情况,一般只出现在 DATA内容不为0的包中,也就是说PSH为1表示的是有真正的TCP数据包内容被传递。TCP的连接建立和连接关闭,都是通过请求-响应的模式完成的。当两个应用进程进行交互式的通信中,有时在一端的应用程序希望在键入一个命令后立即收到对应的响应。在这种情况下,TCP就可以使用推送操作。通常的数据中都会带有PSH,但URG只在紧急数据才设置,也称“带外数据”。

       URG位(URGent):当URG=1时,表示紧急指针字段有效。他告诉系统次报文段有紧急指针,应该尽快的处理(相当于高优先级的数据),而不要按照原来的排序序列来传送。若不使用紧急指针,那么这两个字符将存储在接收TCP的缓存末尾。只有在所有数据段被处理完毕后这两个字符才能被交付到接收方的网应用进程。URG是一个正偏移,与TCP首部中序号字段的值相加表示紧急数据后面的字节,即紧急指针是指向紧急数据最后一个字节的下一字节。

 

TCP协议

 1)、应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,然后TCP把数据流分区成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传输单元(MTU)的限制)。

 2)、TCP把结果包传给IP层,由它来通过网络将包传送给接收端实体的TCP层。TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。

 3)、接收端实体对已成功收到的包发回一个相应的确认(ACK)。如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。TCP用一个校验和函数来检验数据是否有错误,在发送和接收时都要计算校验和。

       TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC793定义。在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能,用户数据报协议(UDP)是同一层内另一个重要的传输协议。在因特网协议族(Internet protocol suite)中,TCP层是位于IP层之上,应用层之下的中间层。不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的包交换。

提起TCP,就不得不提及TCP的三次握手和四次挥手,其过程见下图用例:

 

 

     

三次握手可概括为:请求连接,收到应答,再次请求。                    SYN ----> SYN -------->  ACK

      四次挥手可概括为:主动请求释放,主端收到应答,对端请求释放,对端收到应答。    FIN--------->ACK-------->FIN--------->ACK

 

为何要三次握手呢?两次可以吗?

        三次握手完后的数据传输也是基于请求应答模式的,从而很好的解决了丢包问题。

1)TCP的三次握手最主要是防止已过期的连接再次传到被连接的主机。如果采用两次的话,会出现下面这种情况。

     比如是A机要连到B机,结果发送的连接信息由于某种原因没有到达B机;于是,A机又发了一次,结果这次B收到了,于是就发信息回来,两机就连接。传完东西后,断开。结果这时候,原先没有到达的连接信息突然又传到了B机,于是B机发信息给A,然后B机就以为和A连上了,这个时候B机就在等待A传东西过去。
2)三次握手改成仅需要两次握手,死锁是可能发生
       考虑计算机A和B之间的通信,假定B给A发送一个连接请求分组,A收到了这个分组,并发送了确认应答分组。按照两次握手的协定,A认为连接已经成功地建立了,可以开始发送数据分组。可是,B在A的应答分组在传输中被丢失的情况下,将不知道A是否已准备好,不知道A建议什么样的序列号,B甚至怀疑A是否收到自己的连接请求分组。在这种情况下,B认为连接还未建立成功,将忽略A发来的任何数据分组,只等待连接确认应答分组。而A在发出的分组超时后,重复发送同样的分组,资源会大大浪费。这样就形成了死锁。

 

为何要四次挥手呢?

       四次挥手:连接释放,确保数据能够完成传输。在创建连接时,发送端和接收端分别建立连接并以相应的数据结构进行建立维护,在一定程度上两端处于一个对等的关系。当一放释放连接时,并不能保证对端数据是否发送完毕,所以需要进行释放连接的请求,等待对端确认,所以一来一回,共四次。TCP协议是面向字节流的,是一种流式服务,全双工的。本端发送和接受数据两不误。 

        挥手需要双发都同意才能结束。即关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。

 

 原文:http://whoshell.com/2017/06/18/%E7%BD%91%E7%BB%9C%E5%9F%BA%E7%A1%80%E5%AD%A6%E4%B9%A0%E6%80%BB%E7%BB%93-1/#more

网络基础学习总结(1)

做web开发呢,除了前端后端技术要熟练使用外,想要更进一步学习web原理,那必须还得了解计算机网络的一些基础知识。计算机网络范围其实很广,内容杂多。说来惭愧啊,上学时候,上课都没有认真思考,实验也没有充分发挥主观能动性,浪费了现有硬件资源来对网络进行更深的学习。但是,在日常工作中,对这些原理的东西也不能一概不知。就打算来说说,网络中的一些基础内容,包括:数据传输模型OSI,TCP/IP,TCP协议的建立与释放,IP数据报的传输与数据格式等等。
image

网络通信模型

因为从计算机整个发展到现在的历程来看,从没有操作系统的单太计算机,只是用于数据简单处理的计算机,到后来的批处理系统,多道程序系统,到分时系统,实时系统的发展,计算机处理能力呈现爆炸性增长,伴随着处理能力提升,早起不同的计算机公司开发自己定义的计算机系统以及计算机通信协议,导致了不同的公司或者说不同的硬件底层支持的计算机的通信会很复杂,硬件的异构型造成了计算机通信的成本花费很大。特别是万维网的创建,更是将整个实验室,县城,市区到国家之间的计算机通信互联的现实需求推至顶端。

那么为了不同公司,不同类型的计算机进行通信更高效,方便,那么无规矩不成方圆。权威机构当然就联合起来,共同定制合理有效的计算机通信模型以及协议等等。也是适应时代发展的需要和推动计算机互联网的快速发展的必然结果。

OSI参考模型

该模型定义了不同计算机互联的标准,是设计和描述计算机网络通信的基本框架。开放系统互联参考模型的系统结构共分7层。在该模型中层与层之间进行对等通信,且这种通信只是逻辑上的,真正的通信都是在最底层-物理层实现的,每一层要完成相应的功能,下一层为上一层提供服务,从而把复杂的通信过程分成了多个独立的、比较容易解决的子问题。–引用自百度OSI

下面这张图,把整个OSI协议模型以及每层协议栈上的一些协议给列出来了:(图片来源自网络)
image
该OSI通信框架知道有7层,那七层,每层大致做得什么,有什么作用就够了。在此就不细说了。

TCP/IP参考模型

TCP/IP参考模型是计算机网络的祖父ARPANET和其后继的因特网使用的参考模型。ARPANET是由美国国防部DoD(U.S.Department of Defense)赞助的研究网络。逐渐地它通过租用的电话线连结了数百所大学和政府部门。当无线网络和卫星出现以后,现有的协议在和它们相连的时候出现了问题,所以需要一种新的参考体系结构。这个体系结构在它的两个主要协议出现以后,被称为TCP/IP参考模型(TCP/IP reference model)。–引用自百度TCP/IP参考模型

这个TCP/IP参考模型有四层:网络访问层、网际互联层、传输层(主机到主机)、和应用层。(图片引用自网络)
image

两种模型的比较

共同点
(1)OSI参考模型和TCP/IP参考模型都采用了层次结构的概念。
(2)都能够提供面向连接和无连接两种通信服务机制。

不同点
(1)OSI采用的七层模型,而TCP/IP是四层结构。
(2)TCP/IP参考模型的网络接口层实际上并没有真正的定义,只是一些概念性的描述。而OSI参考模型不仅分了两层,而且每一层的功能都很详尽,甚至在数据链路层又分出一个介质访问子层,专门解决局域网的共享介质问题。
(3)OSI模型是在协议开发前设计的,具有通用性。TCP/IP是先有协议集然后建立模型,不适用于非TCP/IP网络。
(4)OSI参考模型与TCP/IP参考模型的传输层功能基本相似,都是负责为用户提供真正的端对端的通信服务,也对高层屏蔽了底层网络的实现细节。所不同的是TCP/IP参考模型的传输层是建立在网络互联层基础之上的,而网络互联层只提供无连接的网络服务,所以面向连接的功能完全在TCP协议中实现,当然TCP/IP的传输层还提供无连接的服务,如UDP;相反OSI参考模型的传输层是建立在网络层基础之上的,网络层既提供面向连接的服务,又提供无连接的服务,但传输层只提供面向连接的服务。
(5)OSI参考模型的抽象能力高,适合与描述各种网络;而TCP/IP是先有了协议,才制定TCP/IP模型的。
(6)OSI参考模型的概念划分清晰,但过于复杂;而TCP/IP参考模型在服务、接口和协议的 区别上不清楚,功能描述和实现细节混在一起。
(7)TCP/IP参考模型的网络接口层并不是真正的一层;OSI参考模型的缺点是层次过多,划分意义不大但增加了复杂性。
(8)OSI参考模型虽然被看好,由于没把握好时机,技术不成熟,实现困难;相反,TCP/IP参考模型虽然有许多不尽人意的地方,但还是比较成功的。

– 引用自百度

数据通信

在了解了现代计算机之间的数据通信模型后,就可以来具体看看计算机之间是如何进行数据传递的,在传递过程中会遇到什么问题,数据是以什么样的形式进行封装传输的。若是在传输中出现错误,又是如何进行处理的。其实,有很多问题值得我们思考并进行更深层次的理解与代码开发。

因为数据的传输大致就是两种:WLAN广域网内的计算机互联通信以及LAN局域网内的主机进行互联通信。所以其实数据的产生和传输都是需要硬件支持的,若是能了解一些常见的计算机网络硬件如:网络交换机路由器集线器等,还有以太网技术VLAN虚拟局域网,可能会更能加深对整个数据通信过程的理解把。有些硬件中对协议通信的支持能力很高,智能的接收数据,转发数据等等,有些则是常规的数据转发推送等。

数据封装解封流程

因为,从上面模型可以知道。数据的传输过程中,需要经过不同层次的协议栈,那么每个层次对传输的数据是如何处理的呢?[以以太网网络为背景]
其实,在实际数据的通信传输过程中,在发送端:每层协议栈都会在上层协议的基础上,添加本层的头数据或者尾部添加数据。并且,每层添加的协议头部的数据结构其实也是不一样的,因为不同层次的协议栈有不同的处理作用,就造成了有不同的需求,所以协议头当然是不同的。直到封装数据到最后成以太网帧(在以太网中),在硬件设备和网络中进行数据传送。
接收端:因为发送端在发送数据会进行协议层封装,那么接收端就是解封装。根据每次协议层的规则,拆分协议头数据进行记录和处理。直到最后将发送端的应用程序,发送有效数据传输到接收端的具体应用中,进行数据处理。

因为不同层次的协议会对数据处理处理,所以,每个对每个层次的数据的称呼也就不一样了:
物理层: 比特(bit)
链路层: 帧(Frame)
网络层分组数据包(Packet)
传输层数据段(Segment)

上述两端的数据通信流程可以通过图示更加形象的表现处理:
【TCP/IP参考模型】
image
可以看到,从最顶层的应用程的用户数据的产生,传输到下层TCP,会对数据进行TCP首部封装成段数据(segment),在往下层网络层传输,该层会添加IP首部,这时候数据就变成了分组数据包,再往下就是主机到以太网的连接层,封装成以太网帧(frame),添加以太网首部,尾部等等。最后就可以将整个数据发送到网络中。

在大致了解了网络总计算机的数据通信要经过基层协议栈的处理封装,到最后数据传输,再到数据解封到接收端的过程后,就可以对每层的协议进行了解了,看看,每个层次的协议数据结构是怎样的,每层协议的封装的协议头部有什么用,以及每个层次协议栈中有哪些常见的协议,都可以进行了解和学习。

TCP协议栈

在传输层中,主要的协议就是TCP以及UDP协议,前者是面向连接的字节流可靠的数据通信协议;后者是无连接的不可靠的协议。其实,这两种协议在实际应用中都很广泛,并且内部内容还不少。这里因为是基础知识内容学习,就打算只是讲讲tcp协议内容。

什么是TCP(Transmission Control Protocol),可以查看百度TCP。通过名字知道它是传输控制协议。就是在主机通信过程中,在传输层对数据进行控制处理的协议。这个面向连接的可靠服务的协议,功能还不少,包括数据正确性校验,超时重传,窗口流量控制等等。这些功能都是为了支持可靠性而服务的。

TCP数据段数据格式

【1】那么,在传输层中,tcp段数据的内部格式是怎么样的?如下图:
image
可以看到,tcp数据在ip数据包中的位置,以及整个tcp段数据的数据格式。

【2】根据上图的数据段的数据格式,每个位置的字段内容代表什么?

  • 源端口和目的端口号: 这两个字段均为16位长度,表示发送端和接收端的端口,用于确认发送端和接收端的应用程序。发送端的IP地址和端口号以及接收端的IP地址和端口号可以确认一个在internet上的TCP连接(端对端的连接建立)。(PORT + IP : 定位主机与主机上的应用程序)
  • 序列号: 序列号是一个32位长度字段,表示分配给TCP包的编号。序列号用来标识应用程序从TCP的发送端到接收端发送的字节流。当TCP开始连接的时候,发送一个序列号给接收端,连接成功后,这个序列号作为初始序列号ISN。之后连接成功发送的第一个字节的序列号位ISN+1,之后发送数据ISN将按照字节的大小进行递增,当序列号大于2的32次方-后,从0开始。
  • 确认号: 发送方对发送的首字节进行了编号,当接收方成功接收后,发送接收成功的序列号加1标识确认回发送端,发送方再次发送的时候就从这个返回的确认号开始。(三次握手)
  • 头部长度: 表示TCP头部的长度,由于TCP的数据有可选字段,头部长度用于表示头部的长度。该项长度位4位,单位是32位字长的数据。TCP的头部最长为60字节,如果没有可选字段通常是20个字节。
  • 保留位: 6位长度没有使用,必须设置为0.
  • 控制位: 6位长度的控制位,可以多个位一起设置。含义如下表:

    1
    2
    3
    4
    5
    6
    7
    字段 含义
    URG 紧急指针字段
    ACK 表示确认号有效
    PSH 表示接收方需要尽快将此数据交给应用层
    RST 重建连接
    SYN 用于发起一个TCP连接
    FIN 用于表示将要断开TCP的连接
  • 窗口尺寸: 窗口的尺寸也称作接收窗口大小,表示本机上TCP协议可以接收的以字节位单位的数目,本字段为16位长度。

  • TCP校验和: 16位长度,用于校验TCP传输数据的正误,包括TCP头和所有数据,TCP的数据必须强制校验。
  • 紧急指针: 16位长度,只有设置了URG位为1这个字段数据才会有效,他指出了紧急接收数据的字节的顺序编号。
  • 选项: 经常使用的为最大分段长度MSS。tcp连接通常在第一个通信的报文中指明这个选项,它指明当前主机所能接收的最大报文长度。

【3】TCP在linux中代码定义
为了校验或者说从程序员的角度来理解这个TCP协议,最直接的方式就是通过底层代码的方式来看了。那么,在linux系统中,对tcp的定义确实可以看到。
可以查看cat /usr/include/linux/tcp.h可以看到具体的对tcp的数据格式的定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#ifndef _LINUX_TCP_H
#define _LINUX_TCP_H
 
#include <linux/types.h>
#include <asm/byteorder.h>
#include <linux/socket.h>
 
struct tcphdr {
__be16 source; /*源地址端口*/
__be16 dest; /*目的地址端口*/
__be32 seq; /*序列号*/
__be32 ack_seq; /*确认序列号*/
#if defined(__LITTLE_ENDIAN_BITFIELD) /*小端对齐*/
__u16 res1:4, /*保留*/
doff:4, /*偏移(头部长度)*/
fin:1, /*关闭连接标志*/
syn:1, /*请求tcp连接标志*/
rst:1, /*重置连接标志*/
psh:1, /*接收方尽快将数据推送至应用层*/
ack:1, /*确认序列号标志*/
urg:1, /*紧急指针标志*/
ece:1, /*拥塞标志位*/
cwr:1; /*拥塞标志位*/
#elif defined(__BIG_ENDIAN_BITFIELD) /*大端对齐*/
__u16 doff:4,
res1:4,
cwr:1,
ece:1,
urg:1,
ack:1,
psh:1,
rst:1,
syn:1,
fin:1;
#else
#error "Adjust your <asm/byteorder.h> defines"
#endif
__be16 window; /*滑动窗口大小*/
__sum16 check; /*校验和*/
__be16 urg_ptr; /*紧急字段指针*/
};
 
/*
* The union cast uses a gcc extension to avoid aliasing problems
* (union is compatible to any of its members)
* This means this part of the code is -fstrict-aliasing safe now.
*/
union tcp_word_hdr {
struct tcphdr hdr;
__be32 words[5];
};

 

根据上面的tcp端数据的数据格式和上述代码定义结合起来理解,可以发现代码就是按照tcp的数据段的数据格式内容来进行定义的,只不过是区分了内存存储字节的大端对齐还是小端对齐的方式而已。

TCP连接与释放

在理解了传输层协议栈中tcp协议数据段的内部数据格式,以及格式中每个字段代表的内容。接下来就可以来看看一个tcp连接是如何连接和释放的。没错,就是大名鼎鼎的TCP三次握手和四次挥手。

【1】TCP三次握手
在广域网或者局域网内,两台主机要进行tcp的连接,数据交互,都必须遵循TCP/IP协议模型中tcp连接规则:TCP三次握手
即tcp是面向字节流的连接,在确认两个主机可以进行tcp交互的前提是,tcp链路连接必须要在数据交互前建立起来。

TCP三次握手,其实就是TCP连接建立的过程,三次握手的目的是同步连接双方的序列号和确认号并交换TCP窗口大小信息。
因为两台主机要进行tcp数据交互,对于每单独的主机,你得知道双发对于数据包发送的规则,即从那个包开始发送,有什么标志说明某个数据是第一次发送的数据,什么时候你发送过来的数据是结束数据?每次你那边能接收到多少字节的数据?所以,三次握手就是为了数据交互做探测准备的。
image

 

下面来分别说说这个TCP三次握手的细节流程:【主要的就是同步序列号和确认号】

  1. 客户端主机A主动打开,发送连接请求报文段(segment),将tcp连接标志为SYN值为1表示要发起一个连接;将seq序列号:分配给报文段的编号标志)设置为x(TCP规定SYN=1时不能携带数据,x为随机产生的一个值),然后客户端状态进入SYN_SEND。

  2. 服务器端B收到A发送过来的报文,进行确认处理,表示收到的序列号有效,设置ACK=1;因为也要发送一个请求连接进行返回,所以SYN=1;因为服务器端B也要发送报文段数据,所以设置报文序列号为seq=y(这个服务器端B主机的报文段序列号,也是为了客户机A接收到,加1处理设置确认序列号返回用的),这时候,最重要的是设置确认序列号ack,因为在第一步中接收到了主机A发送的序列号x,这时候,接收端需要在接收到的序列号基础上加1,将值x+1作为确认序列号设置到tcp报文段中,所以设置ack=x+1。表示:我已经收到发来的序列号了,确认序列号为x+1,你下次发送报文段数据的序列号就从x+1开始设置,这样,我才认可是你发送的数据,才是有效数据。。

  3. 客户端主机A接收服务器端的反馈数据,进行再次确认,若是得到的ack为第一次发送的序列号基础上加1,那么说明这个报文段是有效的,设置ACK=1;因为不是要求重新发送tcp请求,所以,不用在设置SYN=1了。只是需要校验确认序列号,这边确认成功,还要对接收到的服务器端序列号y进行设置,在y基础上加1,将y+1作为确认序列号设置到报文段的ack字段中,为了让服务器端进行报文校验,即设置ack=y+1(当B端接收到报文段后,获取ack=y+1,说明与上次发送的报文序列号差1,报文段有效),因为确认报文有效了,所以,此时可以将这个发送的报文段的序列号设置为接收来的确认序列号seq=x+1,说明,正式的数据发送已经开始了,从x+1开始的序列号的报文段就是我发送的。

seq序列号表示发送的报文段的报文编号,ack序列号表示对方接收端处理后的确认序列号,用于校验报文段是否正确的。
在三次握手建立好连接之后,就可以进行正常的数据交互了,当然了,每次数据交互发送的报文段都是又这些例如序列号seq,接收方的确认序列号,控制表示,源和目的端口号等等。

为什么客户端要进行二次确认?
因为会出现已失效的连接请求报文情况:
正常来说,客户端发出连接请求,但因为连接请求报文丢失而未收到确认。于是客户端再次发出一次连接请求,后来收到了确认,建立了连接。数据传输完毕后,释放了连接,客户端一共发送了两个连接请求报文段,其中第一个丢失,第二个到达了服务端,没有”已失效的连接请求报文段”。

现在假定一种异常情况,即客户端发出的第一个连接请求报文段并没有丢失,只是在某些网络节点长时间滞留了,以至于延误到连接释放以后的某个时间点才到达服务端。本来这个连接请求已经失效了,但是服务端收到此失效的连接请求报文段后,就误认为这是客户端又发出了一次新的连接请求。于是服务端又向客户端发出请求报文段,同意建立连接。假定不采用三次握手,那么只要服务端发出确认,连接就建立了。

由于现在客户端并没有发出连接建立的请求,因此不会理会服务端的确认,也不会向服务端发送数据,但是服务端却以为新的传输连接已经建立了,并一直等待客户端发来数据,这样服务端的许多资源就这样白白浪费了。

采用三次握手的办法可以防止上述现象的发生。比如在上述的场景下,客户端不向服务端的发出确认请求,服务端由于收不到确认,就知道客户端并没有要求建立连接。

【2】TCP四次挥手
当两段AB的tcp连接传输完成之后,要进行断开,就像tcp连接要进行三次握手才能正确的传递数据;在tcp的断开也要进行一些规则的流程:TCP四次挥手
再来看看tcp四次挥手的流程图:
image

挥手流程分析:

  1. 客户端A主机在得到或者处理完成数据需求之后,就准备关闭连接了,先会发送一个报文给服务器端B主机(没有数据),设置报文控制位FIN=1
    ,要求断开连接。该报文序列号seq设置位u,seq=u,客户端在将该报文发送出去后,就进入FIN_WAIT_1状态。

  2. 服务器端B主机收到了来自客户端的请求后,校验确认序列号后设置ACK=1,同时也设置响应报文序列号seq=v,并将接收到的客户端的报文的序列号+1作为确认序列号,即设置ack=u+1,放回给客户端主机A,此时服务器端进入了CLOSE_WAIT状态。(因为步骤一中客户端A的断开请求又多种情况,主动权也是在客户端主机A,那么就会又这种状况,服务器主机B的应用处理还没又完成,就收到客户端的断开请求,这时候在响应客户端说,服务器收到了断开请求,准备断开后,进入close_wait状态后,就要通知服务器端的处理程序,要进行断开了,至于怎么处理就要看程序的控制了。响应请求未发送FIN控制位值

  3. 当通知完服务器端的应用程序,要进行关闭后,服务器端就会被动关闭,就会发送一个断开请求,FIN=1,并根据上次发送响应报文的确认序列号u+1,又设置同样的值,这样,就说明这此FIN断开请求与上次响应请求是一致的,并同时设置确认序列号有效ACK=1,设置该次请求报文序列号seq=w。这个时候,服务器端进入LAST_ACK状态,即最后一次发送确认序列号。(这次请求是服务器端关闭应用程序后,在被动关闭的状态下发送的断开连接请求。)

  4. 客户端第二次接收到服务器端信息(但是是第一次接收服务器端FIN断开连接请求),即从报文段中知道FIN=1,即服务器请求断开连接了,客户端就会进入TIME_WAIT状态,接着发送一个确认报文,校验收到的服务器端的FIN断开请求,设置ACK=1,报文序列号设置为客户端的第二次发送,即在第一次发送的seq=u的基础上再加1,即seq=u+1,同时ack将会设置为从服务器端B主机接收的报文序列号w的基础上加1,ack=w+1,表明接收到了断开请求且确认序列号有效。最后,服务器端和客户端都会进入CLOSE_WAIT状态。

为什么握手只要三次,挥手却要四次?
因为服务端在LISTEN状态下,收到建立请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而连接关闭时,当收到对方的FIN报文时,仅仅表示对方没有需要发送的数据了,但是还能接收数据,己方未必数据已经全部发送给对方了,所以己方可以立即关闭,也可以将应该发送的数据全部发送完毕后再发送FIN报文给客户端来表示同意现在关闭连接。【LAST_ACK表示没有数据要发送了】

从这个角度而言,再断开连接的时候,服务端的ACK和FIN一般都会分开发送

IP协议栈

在TCP/IP参考模型中的网际层中的IP协议栈,在数据传输过程中,会对上层的tcp处理后的数据段(segment),在此进行封装,加上自己的ip头部数据。
其中,虽然arp,icmp协议并不是该层的协议,但是两者在该层中是与ip协议进行协同工作的。即IP层中包含网际控制报文协议和地址识别协议。
前者ICMP用于报告网络上的某些出错情况,允许网际路由器传输出现差错信息或者测试报文。
后者ARP处于IP层和数据链路层之间,它是用来将32位ip地址与MAC地址转换用的。

关于ip更详细的介绍,参考百度ip

IP数据包数据格式

好了,在简要介绍了网际层的常见协议和作用外,就可以看看该层的数据包中的数据格式和内部字段代表的含义。
【1】数据包数据格式
image
可以看到,相比较TCP的数据段内的数据格式,ip内部的数据也不少。

【2】字段含义
根据上面一步中的IP数据包内部数据格式,下面可以来分别看看内部的字段分别代表了什么意思。

  • 版本号:ip协议的版本号,长度4位,规定网络实现的IP版本。IPV4该值为4。
  • 首部长度: 首部长度指的是IP字段除去数据的整个头部数据长度,是以32位的字作为计算单位。最短的IP头部长度是20字节,最长为60个字节。所以该属性值的可取值范围是5 - 15。
  • 服务类型(TOS): ip服务类型字段长度8位。包括3位优先权,4位T服务类型子字段和1位保留字段:
    1
    2
    3
    字段 优先权 D T R F 保留
    长度 3位 1位 1位 1位 1位 1位
    含义 优先级 延迟 吞吐量 可靠性 费用 未用

其中:后四位字段只能用一个,若是全部为0表示一般服务。服务类型字段由应用程序进行设置,路由器仅在必要的时候进行读取,不会进行设置。

  • 总长度:总长度字段长度16位,表示以字节为单位的数据报文长度,长度包含IP头部和数据部分。 所以ip数据报文总长度可以到达65535个字节长度。
  • 标识和片偏移: IP每次发一份数据报文都会填写一个标识用来表示此数据包,发送完后此值会加1。所以,在传输数据>mtu=1500个字节的时候,需要对数据报文进行分片。在分片的时候,需要对分片的每一个数据设置序号和ip报文来源,都可以在标识种进行设置。还要加上分片数据在源数据报文种的偏移地址,便于接收端收到所有分片的ip数据报进行重新组合。
  • 生存时间: TTL(time to live) 字段的值表示数据报文最多可以经过的路由器的数量。源主机发送数据时候设置TTL(一般为32或者64),没经过一个
    路由器进行分转,TTL的值减一。当TTL=0的时候,路由器会丢弃此包,并发送一个ICMP报文通知源主机。目的: 防止在数据报传输过程种出现错误,引起包在Internet的路由器之间不断循环,因而加入TTL机制限制报文经过的路由总数。
  • 协议类型: 该字段为8位长度,即最多可以表示255种协议类型,表示IP上承载的是什么高级协议。目的是为了在网际层种进行封包和解包的过程中,TCP/IP协议栈知道将这些数据包发给那个层的协议栈做相关的处理。协议类型含义如下表:

    1
    2
    3
    4
    5
    6
    值 协议类型
    1 ICMP
    2 TCP
    6 IMGP
    17 UDP
    ...
  • 头部检验和: 校验和是一个16位长度数值。使用循环冗余校验生成,其作用是保证IP帧的完整性。发送端发送数据的时候要计算CRC16校验值,填写到此
    字段中;接收端会计算IP的校验值并与该字段进行匹配,如果不匹配表示帧发生错误,将丢弃此报文。因为CRC16的计算与TTL有关,所以每次经过路由器都要重新计算。

  • 源地址和目的地址: 即为发送端和接收端主机的ip地址。

【3】ip数据包在linux中代码定义:
若是像查看ip数据包在linux中代码的定义情况,则可以通过命令cat /usr/include/linux/ip.h查看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*IP头部数据结构的定义*/
struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD) /*小端对齐*/
__u8 ihl:4, /*ip头部长度,单位是32bit*/
version:4; /*IP版本,值为4 IPV4*/
#elif defined (__BIG_ENDIAN_BITFIELD) /*大端*/
__u8 version:4, /*版本 ipv4*/
ihl:4; /*IP头部长度*/
#else
#error "Please fix <asm/byteorder.h>"
#endif
__u8 tos; /*服务类型*/
__be16 tot_len; /*总长度*/
__be16 id; /*数据报标识*/
__be16 frag_off; /*分片数据片偏移量*/
__u8 ttl; /*生存时间*/
__u8 protocol; /*协议类型:tcp,udp,icmp,imgp*/
__sum16 check; /*头部校验和*/
__be32 saddr; /*源主机ip地址*/
__be32 daddr; /*目的主机ip地址*/
/*The options start here. */ /*ip选项*/
};

 

可以根据代码中,定义的变量与ip数据包数据格式中字段进行对比就可以知道,代码的编写中变量的定义就是参考ip数据包格式来的。

以太网

在发送端,数据通过应用层到传输层,网际IP层,最后越是贴近物理层,封装成以太网帧(以太网中)进行传输。再来看看这个帧内部信息。

以太网帧数据格式

【1】以太网帧数据格式如下图:
image
可以看到,以太网帧的数据格式挺简单的。包括以太网头部中的:目的mac,源mac,类型。mac代表当前主机和通信主机的硬件地址。类型,则是用于表明当前帧是什么类型的数据帧,是ip数据包,还是arp请求等等。后面还有个以太网尾部CRC,4个字节用来做循环冗余校验的。
其中,通过以太网帧中的数据长度46~1500,就涉及到一个概念MTU,也就是最大传输单元,表明单个帧数据最多能传输1500个字节数据(不包括头部数据)。

【2】帧在linux代码中的定义
若是想查看linux中,是如何对以太网帧进行代码定义的话,可以通过命令cat /usr/include/linux/if_ether.h来查看,可以看到帧的全部字段和类型数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#ifndef _LINUX_IF_ETHER_H
#define _LINUX_IF_ETHER_H
#include <linux/types.h>
/*
* IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble
* and FCS/CRC (frame check sequence).
*/
 
#define ETH_ALEN 6 /* Octets in one ethernet addr 以太网地址:mac地址 */
#define ETH_HLEN 14 /* Total octets in header. 以太网头部的总长度:源地址+目的地址+数据类型 */
#define ETH_ZLEN 60 /* Min. octets in frame sans FCS 不含CRC校验的数据最小长度:46+12+2 */
#define ETH_DATA_LEN 1500 /* Max. octets in payload 帧内数据的最大长度MTU*/
#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS 不含CRC校验和的最大以太网数据长度*/
#define ETH_FCS_LEN 4 /* Octets in the FCS CRC校验和字段长度*/
 
/*
* These are the defined Ethernet Protocol ID's.
下面定义的是以太网头部中类型字段选址:代表不同的数据类型 2个字节 2^16种类型
*/
 
#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */
#define ETH_P_PUP 0x0200 /* Xerox PUP packet */
#define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */
#define ETH_P_TSN 0x22F0 /* TSN (IEEE 1722) packet */
#define ETH_P_IP 0x0800 /* Internet Protocol packet 表示IP数据报文 */
#define ETH_P_X25 0x0805 /* CCITT X.25 */
#define ETH_P_ARP 0x0806 /* Address Resolution packet ARP协议数据类型*/
#define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ] */
#define ETH_P_IEEEPUP 0x0a00 /* Xerox IEEE802.3 PUP packet */
#define ETH_P_IEEEPUPAT 0x0a01 /* Xerox IEEE802.3 PUP Addr Trans packet */
#define ETH_P_BATMAN 0x4305 /* B.A.T.M.A.N.-Advanced packet [ NOT AN OFFICIALLY REGISTERED ID ] */
#define ETH_P_DEC 0x6000 /* DEC Assigned proto */
#define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */
#define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */
#define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */
#define ETH_P_LAT 0x6004 /* DEC LAT */
#define ETH_P_DIAG 0x6005 /* DEC Diagnostics */
#define ETH_P_CUST 0x6006 /* DEC Customer use */
#define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */
#define ETH_P_TEB 0x6558 /* Trans Ether Bridging */
#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */
#define ETH_P_ATALK 0x809B /* Appletalk DDP */
#define ETH_P_AARP 0x80F3 /* Appletalk AARP */
#define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */
#define ETH_P_IPX 0x8137 /* IPX over DIX */
#define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */
#define ETH_P_PAUSE 0x8808 /* IEEE Pause frames. See 802.3 31B */
#define ETH_P_SLOW 0x8809 /* Slow Protocol. See 802.3ad 43B */
#define ETH_P_WCCP 0x883E /* Web-cache coordination protocol
* defined in draft-wilson-wrec-wccp-v2-00.txt */
#define ETH_P_MPLS_UC 0x8847 /* MPLS Unicast traffic */
#define ETH_P_MPLS_MC 0x8848 /* MPLS Multicast traffic */
#define ETH_P_ATMMPOA 0x884c /* MultiProtocol Over ATM */
#define ETH_P_PPP_DISC 0x8863 /* PPPoE discovery messages */
#define ETH_P_PPP_SES 0x8864 /* PPPoE session messages */
#define ETH_P_LINK_CTL 0x886c /* HPNA, wlan link local tunnel */
#define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport
* over Ethernet
*/
#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
#define ETH_P_AOE 0x88A2 /* ATA over Ethernet */
#define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */
#define ETH_P_802_EX1 0x88B5 /* 802.1 Local Experimental 1. */
#define ETH_P_TIPC 0x88CA /* TIPC */
#define ETH_P_MACSEC 0x88E5 /* 802.1ae MACsec */
#define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */
#define ETH_P_MVRP 0x88F5 /* 802.1Q MVRP */
#define ETH_P_1588 0x88F7 /* IEEE 1588 Timesync */
#define ETH_P_NCSI 0x88F8 /* NCSI protocol */
#define ETH_P_PRP 0x88FB /* IEC 62439-3 PRP/HSRv0 */
#define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */
#define ETH_P_TDLS 0x890D /* TDLS */
#define ETH_P_FIP 0x8914 /* FCoE Initialization Protocol */
#define ETH_P_80221 0x8917 /* IEEE 802.21 Media Independent Handover Protocol */
#define ETH_P_HSR 0x892F /* IEC 62439-3 HSRv1 */
#define ETH_P_LOOPBACK 0x9000 /* Ethernet loopback packet, per IEEE 802.3 */
#define ETH_P_QINQ1 0x9100 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
#define ETH_P_QINQ2 0x9200 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
#define ETH_P_QINQ3 0x9300 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
#define ETH_P_EDSA 0xDADA /* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
#define ETH_P_AF_IUCV 0xFBFB /* IBM af_iucv [ NOT AN OFFICIALLY REGISTERED ID ] */
 
#define ETH_P_802_3_MIN 0x0600 /* If the value in the ethernet type is less than this value
* then the frame is Ethernet II. Else it is 802.3 */
 
/*
* Non DIX types. Won't clash for 1500 types.【MTU】
*/
 
#define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */
#define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */
#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */
#define ETH_P_802_2 0x0004 /* 802.2 frames */
#define ETH_P_SNAP 0x0005 /* Internal only */
#define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */
#define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/
#define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */
#define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */
#define ETH_P_CAN 0x000C /* CAN: Controller Area Network */
#define ETH_P_CANFD 0x000D /* CANFD: CAN flexible data rate*/
#define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/
#define ETH_P_TR_802_2 0x0011 /* 802.2 frames */
#define ETH_P_MOBITEX 0x0015 /* Mobitex (kaz@cafe.net) */
#define ETH_P_CONTROL 0x0016 /* Card specific control frames */
#define ETH_P_IRDA 0x0017 /* Linux-IrDA */
#define ETH_P_ECONET 0x0018 /* Acorn Econet */
#define ETH_P_HDLC 0x0019 /* HDLC frames */
#define ETH_P_ARCNET 0x001A /* 1A for ArcNet :-) */
#define ETH_P_DSA 0x001B /* Distributed Switch Arch. */
#define ETH_P_TRAILER 0x001C /* Trailer switch tagging */
#define ETH_P_PHONET 0x00F5 /* Nokia Phonet frames */
#define ETH_P_IEEE802154 0x00F6 /* IEEE802.15.4 frame */
#define ETH_P_CAIF 0x00F7 /* ST-Ericsson CAIF protocol */
#define ETH_P_XDSA 0x00F8 /* Multiplexed DSA protocol */
 
/*
* This is an Ethernet frame header.
*/
 
struct ethhdr {
unsigned char h_dest[ETH_ALEN]; /* destination eth addr 以太网目的Mac地址 */
unsigned char h_source[ETH_ALEN]; /* source ether addr 以太网源MAC地址*/
__be16 h_proto; /* packet type ID field 以太网包类型:16位*/
} __attribute__((packed));
 
 
#endif /* _LINUX_IF_ETHER_H */

 

硬件设备

不同层次对应的硬件配置:(通常情况下,不包括三层交换机,四层交换机..)
物理层:网卡,网线,集线器,中继器,调制解调器
数据链路层:网桥,交换机
网络层:路由器

网关工作在第四层传输层及其以上
集线器是物理层设备,采用广播的形式来传输信息。
交换机就是用来进行报文交换的机器。多为链路层设备(二层交换机),能够进行地址学习,采用存储转发的形式来交换报文.。
路由器的一个作用是连通不同的网络,另一个作用是选择信息传送的线路。选择通畅快捷的近路,能大大提高通信速度,减轻网络系统通信负荷,节约网络系统资源,提高网络系统畅通率。

交换机和路由器的区别?
交换机拥有一条很高带宽的背部总线和内部交换矩阵。交换机的所有的端口都挂接在这条总线上,控制电路收到数据包以后,处理端口会查找内存中的地址对照表以确定目的MAC(网卡的硬件地址)的NIC(网卡)挂接在哪个端口上,通过内部交换矩阵迅速将数据包传送到目的端口,目的MAC若不存在则广播到所有的端口,接收端口回应后交换机会“学习”新的地址,并把它添加入内部MAC地址表中。

使用交换机也可以把网络“分段”,通过对照MAC地址表,交换机只允许必要的网络流量通过交换机。通过交换机的过滤和转发,可以有效的隔离广播风暴,减少误包和错包的出现,避免共享冲突。

交换机在同一时刻可进行多个端口对之间的数据传输。每一端口都可视为独立的网段,连接在其上的网络设备独自享有全部的带宽,无须同其他设备竞争使用。当节点A向节点D发送数据时,节点B可同时向节点C发送数据,而且这两个传输都享有网络的全部带宽,都有着自己的虚拟连接。假使这里使用的是10Mbps的以太网交换机,那么该交换机这时的总流通量就等于2×10Mbps=20Mbps,而使用10Mbps的共享式HUB时,一个HUB的总流通量也不会超出10Mbps。

总之,交换机是一种基于MAC地址识别,能完成封装转发数据包功能的网络设备。交换机可以“学习”MAC地址,并把其存放在内部地址表中,通过在数据帧的始发者和目标接收者之间建立临时的交换路径,使数据帧直接由源地址到达目的地址。

从过滤网络流量的角度来看,路由器的作用与交换机和网桥非常相似。但是与工作在网络物理层,从物理上划分网段的交换机不同,路由器使用专门的软件协议从逻辑上对整个网络进行划分。例如,一台支持IP协议的路由器可以把网络划分成多个子网段,只有指向特殊IP地址的网络流量才可以通过路由器。对于每一个接收到的数据包,路由器都会重新计算其校验值,并写入新的物理地址。因此,使用路由器转发和过滤数据的速度往往要比只查看数据包物理地址的交换机慢。但是,对于那些结构复杂的网络,使用路由器可以提高网络的整体效率。路由器的另外一个明显优势就是可以自动过滤网络广播。

集线器与路由器在功能上有什么不同?

首先说HUB,也就是集线器。它的作用可以简单的理解为将一些机器连接起来组成一个局域网。而交换机(又名交换式集线器)作用与集线器大体相同。但是两者在性能上有区别:集线器采用的式共享带宽的工作方式,而交换机是独享带宽。这样在机器很多或数据量很大时,两者将会有比较明显的。而路由器与以上两者有明显区别,它的作用在于连接不同的网段并且找到网络中数据传输最合适的路径。路由器是产生于交换机之后,就像交换机产生于集线器之后,所以路由器与交换机也有一定联系,不是完全独立的两种设备。路由器主要克服了交换机不能路由转发数据包的不足

总的来说,路由器与交换机的主要区别体现在以下几个方面:

(1)工作层次不同
最初的的交换机是工作在数据链路层,而路由器一开始就设计工作在网络层。由于交换机工作在数据链路层,所以它的工作原理比较简单,而路由器工作在网络层,可以得到更多的协议信息,路由器可以做出更加智能的转发决策。

(2)数据转发所依据的对象不同
交换机是利用物理地址或者说MAC地址来确定转发数据的目的地址。而路由器则是利用IP地址来确定数据转发的地址。IP地址是在软件中实现的,描述的是设备所在的网络。MAC地址通常是硬件自带的,由网卡生产商来分配的,而且已经固化到了网卡中去,一般来说是不可更改的。而IP地址则通常由网络管理员或系统自动分配。

(3)传统的交换机只能分割冲突域,不能分割广播域;而路由器可以分割广播域
由交换机连接的网段仍属于同一个广播域,广播数据包会在交换机连接的所有网段上传播,在某些情况下会导致通信拥挤和安全漏洞。连接到路由器上的网段会被分配成不同的广播域,广播数据不会穿过路由器。虽然第三层以上交换机具有VLAN功能,也可以分割广播域,但是各子广播域之间是不能通信交流的,它们之间的交流仍然需要路由器。

(4)路由器提供了防火墙的服务
路由器仅仅转发特定地址的数据包,不传送不支持路由协议的数据包传送和未知目标网络数据包的传送,从而可以防止广播风暴。

该部分截取自:OSI七层模型详解

总结

上面的内容仅仅是网络的很小很小的基础知识部分,也是自己学习过程中一些总结。包括数据通信的OSI/TCP参考模型,并对数据通信中每层的协议栈进行分析和内部数据结构的图解,同时也将linux系统对每层协议的代码定义也罗列出来,帮助程序员加深理解。其实,内部还有很多东西值得去学习,分析,思考。这篇就到这….
image


参考:

Liux网络编程(第二版)

TCP:三次握手、四次握手、backlog及其他

 

posted @ 2018-01-21 23:34  liujiacai  阅读(2725)  评论(0编辑  收藏  举报