友情链接购买网站,信息推广,wordpress退货插件,设计素材网站版权问题这个图很形象的展示了OSI的五层架构之间的关系。OSI被称为开放式互联#xff0c;是国际标准组织制定的网络模型#xff0c;本来是七层#xff0c;后来把表现层和会话层加到应用层里面了。那么五层模型中的每一层具体都是干什么的呢#xff1f;在标准的网络模型中#xff0…这个图很形象的展示了OSI的五层架构之间的关系。OSI被称为开放式互联是国际标准组织制定的网络模型本来是七层后来把表现层和会话层加到应用层里面了。那么五层模型中的每一层具体都是干什么的呢在标准的网络模型中每一层都有它不同的用处而且每一层都只提供向上和向下的接口而不会垮层去通信。在应用层这里主要是为特定的应用程序提供数据传输服务。这一层是和程序员关系最紧密的一层其中的代表性协议就是http它的数据单位是报文。在传输层为进程提供数据传输服务。这一层主要为应用层的各种各样的协议提供通用的传输层协议。这里主要就是两个最简单的协议TCP协议和UDP协议。这里传输是端到端连接的是端口号也就是进程。在网络层为主机提供数据传输服务。这一层主要将传输层的数据报封装成分组。经典协议就是IP协议。在数据链路层为同一链路的主机提供数据传输服务。将网络层传下来的分组封装成帧这里主要是MAC地址。在物理层最底层传输的是二进制比特流。我们从网络层说起一般网络层下面的就不去了解了。网络层是整个互联网的核心。网络层向上只提供简单灵活的、无连接的。尽最大努力交互的数据报服务。IP数据报的格式版本众所周知ip现在有两个版本ipv4和ipv6ipv4的地址已经用光了ipv6地址非常多。首部长度上面每一行是4个字节除去可变部分最少有五行因此就是20个字节。总长度首部长度数据部分长度生存时间TTL它的存在是为了防止无法交付的数据报在互联网中不断兜圈子。以路由器跳数为单位当 TTL 为 0 时就丢弃数据报。协议携带的数据应该上交的处理协议传输层的协议。首部检验和因为数据报每经过一个路由器都要重新计算检验和因此检验和不包含数据部分可以减少计算的工作量。标识为了在分片的情况下仍然使不同分片具有相同的标识。片偏移在分片的时候使用。源地址、目标地址ip以上就是ip数据报的格式当然最后还要加上要传输的数据部分了。可以看的出ip的首部规定了ip协议的很多属性内容。那么ip地址是怎么编码的呢ip地址的编码方式经历了三个历史阶段分类由两部分组成网络号和主机号其中不同分类具有不同的网络号长度并且是固定的A类地址0网络地址(7位) 主机地址(24位)B类地址10网络地址(14位)主机地址(16位)C类地址110网络地址(21位)主机地址(8位)D类地址1110 多目的广播地址(28位)E类地址11110 保留用于实验室和将来使用注意在各类IP地址中有一些IP地址用于表示特殊用途不用于作主机IP地址主机号全为0表示网络本身主机号全为1表示本网络的广播地址127.0.0.1网络保留作为环路自测地址此地址表示任意主机本身32bit全为0即0.0.0.0表示整个TCP/IP网络32bit全为1即255.255.255.255表示整个TCP/IP网络的广播地址。子网划分通过在主机号字段中拿一部分作为子网号把两级 IP 地址划分为三级 IP 地址。IP 地址 :: { 网络号 , 子网号 , 主机号 }要使用子网必须配置子网掩码。一个 B 类地址的默认子网掩码为 255.255.0.0如果 B 类地址的子网占两个比特那么子网掩码为 11111111 11111111 11000000 00000000也就是 255.255.192.0。注意外部网络看不到子网的存在。无分类无分类编址 CIDR 消除了传统 A 类、B 类和 C 类地址以及划分子网的概念使用网络前缀和主机号来对 IP 地址进行编码网络前缀的长度可以根据需要变化。IP 地址 :: { 网络前缀号 , 主机号 }CIDR 的记法上采用在 IP 地址后面加上网络前缀长度的方法例如 128.14.35.7/20 表示前 20 位为网络前缀。CIDR 的地址掩码可以继续称为子网掩码子网掩码首 1 长度为网络前缀的长度。一个 CIDR 地址块中有很多地址一个 CIDR 表示的网络就可以表示原来的很多个网络并且在路由表中只需要一个路由就可以代替原来的多个路由减少了路由表项的数量。把这种通过使用网络前缀来减少路由表项的方式称为路由聚合也称为 构成超网。在路由表中的项目由“网络前缀”和“下一跳地址”组成在查找时可能会得到不止一个匹配结果应当采用最长前缀匹配来确定应该匹配哪一个。以上这部分不太懂。在数据链路层实现通信的过程中ip数据报的源地址和目标地址不会发生改变但MAC的地址会随着链路的改变而改变从上图也可以看出通信过程中从一个路由器跳到另一个路由器他们的MAC都不相同那么怎么由ip地址来得到不同路由器的MAC地址呢使用的是地址解析协议ARP协议。每一个主机都会有一个ARP高速缓存里面存放着本局域网内个主机和路由器之间的ip到MAC的映射。如果主机 A 知道主机 B 的 IP 地址但是 ARP 高速缓存中没有该 IP 地址到 MAC 地址的映射此时主机 A 通过广播的方式发送 ARP 请求分组主机 B 收到该请求后会发送 ARP 响应分组给主机 A 告知其 MAC 地址随后主机 A 向其高速缓存中写入主机 B 的 IP 地址到 MAC 地址的映射。ARP协议的作用就是建立ip到MAC的映射完成ip数据报在数据链路层的传输。那么路由器是如何分组转发的呢从数据报的首部提取目的主机的 IP 地址 D得到目的网络地址 N。若 N 就是与此路由器直接相连的某个网络地址则进行直接交付若路由表中有目的地址为 D 的特定主机路由则把数据报传送给表中所指明的下一跳路由器若路由表中有到达网络 N 的路由则把数据报传送给路由表中所指明的下一跳路由器若路由表中有一个默认路由则把数据报传送给路由表中所指明的默认路由器报告转发分组出错。在传输过程中如何控制报文的状态使用的是网络控制报文协议(ICMP)作用是更有效的转发ip数据报提高交付成功的机会。比如常用的ping应用来测试两台主机之间的联通性。Ping 的原理是通过向目的主机发送 ICMP Echo 请求报文目的主机收到之后会发送 Echo 回答报文。Ping 会根据时间和成功响应的次数估算出数据包往返时间以及丢包率。以上就是网络层的东西主要就是ip协议的格式还有与之配套的ARP协议和ICMP协议。传输层TCP和UDPUDP协议用户数据报协议是无连接的尽最大可能交付没有拥塞控制(不会拥塞因为无连接)、面向报文(对应用层的报文不拆分只添加首部)、支持一对一一对多多对多等。TCP协议传输控制协议面向连接的提供可靠交付(交付成功)、有流量控制、有拥塞控制(因为是面向连接的)、提供全双工通信、面向字节流(把报文看成字节流将字节流组织成大小不等的数据块)一对一。UDP的首部格式源端口、目标端口、长度、检验和TCP的首部格式这里有几个很重要的参数序号用于对字节流进行编号例如序号为 301表示第一个字节的编号为 301如果携带的数据长度为 100 字节那么下一个报文段的序号应为 401。确认号期望收到的下一个报文段的序号。例如 B 正确收到 A 发送来的一个报文段序号为 501携带的数据长度为 200 字节因此 B 期望下一个报文段的序号为 701B 发送给 A 的确认报文段中确认号就为 701。数据偏移首部长度确认ACK当 ACK1 时确认号字段有效否则无效。TCP 规定在连接建立后所有传送的报文段都必须把 ACK 置 1。刚开始为0同步SYN在连接建立时用来同步序号。当 SYN1ACK0 时表示这是一个连接请求报文段。若对方同意建立连接则响应报文中 SYN1ACK1。终止FIN用来释放一个连接当 FIN1 时表示此报文段的发送方的数据已发送完毕并要求释放连接。窗口在拥塞中很重要的概念窗口值作为接收方让发送方设置其发送窗口的依据。之所以要有这个限制是因为接收方的数据缓存空间是有限的。在后面详细说重要TCP的三次握手看上面这个图表示的很清楚首先握手的概念就是一次发送数据的操作不管是客户端向服务端还是服务端向客户端。服务端一直在监听自己的端口号查看是否有请求进来。客户端主动开启请求将同步SYN打开为1然后发送了一个序号为x的数据报。这是第一次握手。服务端监听到了这次请求看到了客户端发了一个序号为x的数据报它就向客户端进行了响应为了保证客户端能收到这次响应那么它需要给客户端提一个要求看客户端能不能实现。因此它的响应就是要求客户端发送一个x序号的下一个序号的数据报。这样就能保证服务端的响应是针对上一个序号x的请求。这是第二次握手。(只有这两次握手可以了吗貌似可以了因此客户端如果接到了这个响应就知道自己上一个请求被响应了但事实不是如此)客户端需要把服务端要求的数据报发给服务端seqx。这就是第三次握手。为什么是三次握手而不是两次握手在上面分析了在第二次握手之后客户端知道自己的上一次请求已经被服务端接收到了。但服务端不知道自己发的响应是不是被客户端接收到因此要想双方都能维护自己的序列号必须进行第三次握手让服务端知道自己的响应被拿到了。为了实现可靠数据传输 TCP 协议的通信双方 都必须维护一个序列号 以标识发送出去的数据包中 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值 并确认对方已经收到了序列号起始值的必经步骤如果只是两次握手 至多只有连接发起方的起始序列号能被确认 另一方选择的序列号则得不到确认当然还有一个原因就是客户端发送的请求在网络中滞留隔很长时间才能收到服务器的连接确认但在此之前客户端会在超时之后尝试重新请求连接这样这个重新请求的连接也会到达服务端如果只有两次握手服务器就会打开两个连接。但这不是我们的本意我们希望它只有一个连接因此。如果加了第三次握手那么客户端会忽略哪个重新尝试请求的确认响应而是对开始时的响应进行确认。因此不进行第三次握手服务端不会再次打开连接。TCP的四次挥手要保证全双工通信的正确关闭需要四次挥手过程。服务端仍然保持监听状态而客户端发起主动关闭的请求发送FIN1表示要关闭了。同时发送此时的序列号u。 第一次挥手服务端监听到了这次关闭请求然后进入CLOSE-WAIT状态就是等着关闭了但还有数据没有发送完成先将这些数据发送完。这时客户端不能向服务器发送消息因为是CLOSE-WAIT状态。为的是让服务端把没交付的数据都发送完成。 第二次挥手然后服务端也向客户端发起确认关闭的请求发送了一个FIN1表示我也要关了。这时就不是CLOSE-WAIT状态了到了LAST-ACK最后确认阶段。此时客户端可以向服务器发送数据了。 第三次挥手客户端收到了服务到请求关闭的请求客户端会向服务端发出一个确认请求表示我收到了你的关闭确认请求当发送完了以后客户端不会立刻关闭而是等待两个2个最大报文存活时间。然后释放。 第四次挥手服务器收到客户端的请求之后立刻关闭连接。可以三次挥手吗先来回答这个问题第二次挥手和第三次挥手的区别第二次挥手有两个作用一个是确认收到客户端的关闭请求一个就是向客户端传送未完的数据。第三次挥手的作用是向客户端发起关闭请求。因此当服务端不需要对客户端传送数据的时候就可以把第二次挥手和第三次挥手合并最终三次挥手就能关闭。TIME_WAIT是客户端在最后向服务端挥手后要等待释放的时间。TIME_WAIT的作用1.可靠的实现TCP全双工通信的终止很好理解在最后一次挥手的时候如果没有被服务端接收到服务端会重新发送FIN请求因此客户端需要维持一段时间来看服务端会不会重发。2.允许老的重复分节在网络中消逝TCP分节可能由于路由器异常而“迷途”在迷途期间TCP发送端可能因确认超时而重发这个分节迷途的分节在路由器修复后也会被送到最终目的地这个原来的迷途分节就称为lost duplicate。在关闭一个TCP连接后马上又重新建立起一个相同的IP地址和端口之间的TCP连接后一个连接被称为前一个连接的化身(incarnation)那么有可能出现这种情况前一个连接的迷途重复分组在前一个连接终止后出现从而被误解成从属于新的化身。为了避免这个情况TCP不允许处于TIME_WAIT状态的连接启动一个新的化身因为TIME_WAIT状态持续2MSL就可以保证当成功建立一个TCP连接的时候来自连接先前化身的重复分组已经在网络中消逝。大量TIME_WAIT造成的影响在高并发短链接的TCP服务器上服务器处理完请求后会立即主动的正常关闭连接这样的场景下会出现大量的socker处于TIME_WAIT状态如果客户端并发量持续很高那么部分客户端就会显示连接不到。TCP可靠传输1.确认和重传接收方收到报文会确认发送方没有收到确认过一段时间会重传。2.数据校验3.数据合理分片和排序UDPIP数据报大于1500字节,大于MTU.这个时候发送方IP层就需要分片(fragmentation).把数据报分成若干片,使每 一片都小于MTU.而接收方IP层则需要进行数据报的重组.这样就会多做许多事情,而更严重的是,由于UDP的特性,当某一片数据传送中丢失时,接收方便 无法重组数据报.将导致丢弃整个UDP数据报.(MTU为最大传输单元)TCP按照MTU合理分片接收方会缓存未按序到达的数据重新排序后再交给应用层。4.流量控制当接收方来不及处理发送方的数据能提示发送方降低发送速率。防止包丢失。5.拥塞控制当网络拥塞时减少数据的发送。TCP滑动窗口发送窗口在没有收到接收窗口的确认下发送方可以连续的把发送窗口的数据发送出去。接收窗口接收方在没有给发送方确认的情况下允许连续接收的大小。滑动的含义发送窗口内的字节都允许被发送接收窗口内的字节都允许被接收。如果发送窗口左部的字节已经发送并且收到了确认那么就将发送窗口向右滑动一定距离直到左部第一个字节不是已发送并且已确认的状态接收窗口的滑动类似接收窗口左部字节已经发送确认并交付主机就向右滑动接收窗口。发送窗口有四个组成部分已发送并收到确认的数据(不再发送窗口和发送缓冲区之内)(这部分可以往右移给其他数据让路)已发送但未收到确认的数据(位于发送窗口之中)(等待确认)允许发送但尚未发送的数据(等待发送)发送窗口外发送缓冲区内暂时不允许发送的数据(等待允许)在上图中A向B发送26.。。。30,这些是已经确认的已经右移出窗口了51往后的是没有被允许发送的还没有进入窗口窗口中只有已发送还没接收的和允许发送还没发送的。B接收A的B接收到了31.。。。。41但B确认的时候是按序确认31是按序到达的因此B会确认但34不是按序到达的因此B不会确认需要A重发32然后才会确认。流量控制从上图就可以知道返回的ACK中会包含自己的接收窗口的大小并且利用大小来控制发送方的数据发送拥塞控制如果网络出现拥塞分组将会丢失此时发送方会继续重传从而导致网络拥塞程度更高。因此当出现拥塞时应当控制发送方的速率。这一点和流量控制很像但是出发点不同。流量控制是为了让接收方能来得及接收而拥塞控制是为了降低整个网络的拥塞程度。TCP主要通过四个算法来进行拥塞控制1.慢开始与拥塞避免慢开始和拥塞控制算法目的在拥塞发生时循序减少主机发送到网络中的分组数使得发生拥塞的路由器有足够的时间把队列中积压的分组处理完毕。发送的最初执行慢开始令 cwnd 1发送方只能发送 1 个报文段当收到确认后将 cwnd 加倍因此之后发送方能够发送的报文段数量为2、4、8 ...注意到慢开始每个轮次都将 cwnd 加倍这样会让 cwnd 增长速度非常快从而使得发送方发送的速度增长速度过快网络拥塞的可能性也就更高。设置一个慢开始门限 ssthresh当 cwnd ssthresh 时进入拥塞避免每个轮次只将 cwnd 加 1。如果出现了超时则令 ssthresh cwnd / 2然后重新执行慢开始。看上面这个图很好理解慢开始的时候cwnd1这时候只允许发送方发送一个数据报但当收到确认的时候就可以发送2个4个。。。。然后设置一个拥塞避免的门限如果超过这个门限就开始每次只增加1个报文数量。当确认超时以后又重新从慢开始出发。2.快重传和快恢复快重传和快恢复则是为了减少因为拥塞导致的数据包丢失带来的重传时间从而避免传递无用的数据到网络。在接收方要求每次接收到报文段都应该对最后一个已收到的有序报文段进行确认。例如已经接收到 M1和 M2此时收到 M4应当发送对 M2的确认。在发送方如果收到三个重复确认那么可以知道下一个报文段丢失此时执行快重传立即重传下一个报文段。例如收到三个 M2则 M3丢失立即重传 M3。在这种情况下只是丢失个别报文段而不是网络拥塞。因此执行快恢复令 ssthresh cwnd / 2 cwnd ssthresh注意到此时直接进入拥塞避免。慢开始和快恢复的快慢指的是 cwnd 的设定值而不是 cwnd 的增长速率。慢开始 cwnd 设定为 1而快恢复 cwnd 设定为 ssthresh。TCP粘包情况发送方发送的若干包数据到接收方接收时粘成一包从接收缓冲区看后一包数据的头紧接着前一包数据的尾。以上就是计算机网络的底层原理。我们重点说了OSI的五层协议并且讲了ip协议的首部格式(版本、首部长度、协议、源地址。目标地址、标识。偏移量)然后着重讲了TCP协议三次握手、四次挥手。然后讲了TCP的滑窗机制。接下来讲讲套接字socket。数据在网络中以有限大小的包形式传输的这些包被称为数据报每一个数据报都包含一个首部和有效载荷。首部包含了地址和端口和其他的管理信息。socket让程序员可以将网络连接视为另一种可以读取的字节的流。掩盖了网络的底层细节。java中的Socket类使用直接代码通过主机操作系统的本地TCP通信栈进行通信。socket是应用程序与TCP/IP协议的封装程序员通过调用API就能实现通信。从上图可以看出套接字位于应用程序和传输层之间使用门面模式将复杂的TCP/IP协议隐藏在socket后面。来看上面这张图先从服务器说起服务器先初始化Socket然后与端口绑定对端口进行监听调用accept阻塞等待客户端连接。这时客户端初始化了一个Socket然后连接服务器如果连接成功那么就建立了连接。进行数据的读写。最后关闭连接。在Uinx里面socket就是一个文件 用打开-读写-关闭模式来操作。套接字的介绍就是这样了。下面介绍IO模型