计算机网络整理

计网体系结构

OSI七层

物理层,数据链路层,网络层,运输层,会话层,表示层,应用层

TCP/IP四层

网络接口层,网际层(IP),运输层(TCP,UDP),应用层

五层

物理层,数据链接层,网络层,运输层,应用层

TCP和UDP区别

  • TCP 面向连接,UDP 是无连接的;
  • TCP 提供可靠的服务,也就是说,通过 TCP 连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP 尽最大努力交付,即不保证可靠交付
  • TCP 的逻辑通信信道是全双工的可靠信道;UDP 则是不可靠信道
    每一条 TCP 连接只能是点到点的;UDP 支持一对一,一对多,多对一和多对多的交互通信
  • TCP 面向字节流(可能出现黏包问题),实际上是 TCP 把数据看成一连串无结构的字节流;UDP 是面向报文的(不会出现黏包问题)
  • UDP 没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如 IP 电话,实时视频会议等)
  • TCP 首部开销20字节;UDP 的首部开销小,只有 8 个字节

字节流和报文的区别

  • TCP将应用层传过来的报文进行分段,放在发送缓冲区里,TCP发送的时候不管发送的是什么东西,直接按连续字节进行发送。
  • UDP将应用层传过来的报文直接加上头部进行发送,udp也没有缓冲区

TCP粘包

  • 原因

    TCP 是一个基于字节流的传输服务(UDP 基于报文的),“流” 意味着 TCP 所传输的数据是没有边界的。所以可能会出现两个数据包黏在一起的情况。

  • 解决

    发送定长包。如果每个消息的大小都是一样的,那么在接收对等方只要累计接收数据,直到数据等于一个定长的数值就将它作为一个消息。
    包头加上包体长度。包头是定长的 4 个字节,说明了包体的长度。接收对等方先接收包头长度,依据包头长度来接收包体。
    在数据包之间设置边界,如添加特殊符号 \r\n 标记。FTP 协议正是这么做的。但问题在于如果数据正文中也含有 \r\n,则会误判为消息的边界。
    使用更加复杂的应用层协议。

http和https

  • 开销:HTTPS 协议需要到 CA 申请证书,一般免费证书很少,需要交费;

  • 资源消耗:HTTP 是超文本传输协议,信息是明文传输,HTTPS 则是具有安全性的 ssl 加密传输协议,需要消耗更多的 CPU 和内存资源;

  • 端口不同:HTTP 和 HTTPS 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443;

  • 安全性:HTTP 的连接很简单,是无状态的;HTTPS 协议是由 TSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 HTTP 协议安全

实现udp可靠化

  • 发送队列和接收队列
  • ACK、RTO计算、ARQ

    ACK确认比特 (ack确认号)
    连接的往返时间成为 RTT
    重传的超时时间 RTO
    ARQ自动重传请求

  • 流量控制、拥塞控制

三次握手

计算机网络太难?了解这一篇就够了

  • A为客户端,B为服务器
  • 一开始B创建传输控制块TCB,等待接受。然后A也创建TCB,向A发送请求,tcp报文段中SYN=1,seq=x.这次传输不传输数据
  • 然后B接收到后,如果同意链接,发送报文段,SYN=1,ACK=1,seq=y,ack=x+1.
  • 然后a接收到后,向B再发送确实报文,SYN=1,ACK=1,seq = x+1,ack = y+1。这里可以带数据也可以不带,不带的话不消耗序号,下次传输再seq=x+1

为什么不二次

  • 防止信道内存在堵塞的报文,在结束链接后再次发给B,然后B就同意链接,一直等待a发送数据,导致资源消耗。如果三次链接的话,就要b再次收到a的确认报文才会建立链接

为什么不四次

  • 完全可靠的通信协议是不存在的。在经过三次握手之后,客户端和服务端已经可以确认之前的通信状况,都收到了确认信息。所以即便再增加握手次数也不能保证后面的通信完全可靠,所以是没有必要的。

四次挥手

  • A->B FIN=1,seq=u(消耗一个序号),A进入终止等待1
  • B->A ACK=1,ack=u+1,seq=y(B进入关闭等待,a到b已经无数据传送,b到a还要继续传输剩下的数据),然后a接收到后进入终止等待2,等待b发送终止信号
  • B->A FIN=1,seq=w,ACK=1,ack=u+1(重新发送ACK=1和ack=u+1),此时B处于最后确认
  • A->B ACK=1,seq=u+1,ack=w+1(seq因为消耗了一个序号所以为u+1),b接收到后关闭,a进入等待。TCP 连接还没有释放掉。必须经过时间等待计时器设置的时间 2MSL(MSL:最长报文段寿命)后,A 才能进入到 CLOSED 状态,然后撤销传输控制块,结束这次 TCP 连接。

二三次合并?

  • 当服务器执行第二次挥手之后, 此时证明客户端不会再向服务端请求任何数据, 但是服务端可能还正在给客户端发送数据(可能是客户端上一次请求的资源还没有发送完毕),所以此时服务端会等待把之前未传输完的数据传输完毕之后再发送关闭请求。

2MSL?

  • 保证第四次挥手时,tcp报文不会丢失,导致a关闭了,b没关,所以在2msl内要是有b发送的重传报文则需要重新发送,并重新计时

  • 防止已失效的连接请求报文段出现在本连接中。A 在发送完最后一个 ACK 报文段后,再经过时间 2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样就可以使下一个连接中不会出现这种旧的连接请求报文段。

保活计时器?

  • 服务器每收到一次客户的数据,就重新设置保活计时器,时间的设置通常是两个小时。若两个小时都没有收到客户端的数据,服务端就发送一个探测报文段,以后则每隔 75 秒钟发送一次。若连续发送 10个 探测报文段后仍然无客户端的响应,服务端就认为客户端出了故障,接着就关闭这个连接。

TCP如何保证可靠传输

  • 数据包校验
  • 对失序数据包重排序
  • 丢弃重复数据
  • 应答机制(ack确认)
  • 超时重发
  • 流量控制,拥塞控制

滑动窗口

  • TCP 利用滑动窗口实现流量控制的机制。滑动窗口(Sliding window)是一种流量控制技术。早期的网络通信中,通信双方不会考虑网络的拥挤情况直接发送数据。由于大家不知道网络拥塞状况,同时发送数据,导致中间节点阻塞掉包,谁也发不了数据,所以就有了滑动窗口机制来解决此问题。

  • TCP 中采用滑动窗口来进行传输控制,滑动窗口的大小意味着接收方还有多大的缓冲区可以用于接收数据。发送方可以通过滑动窗口的大小来确定应该发送多少字节的数据。当滑动窗口为 0 时,发送方一般不能再发送数据报,但有两种情况除外,一种情况是可以发送紧急数据,例如,允许用户终止在远端机上的运行进程。另一种情况是发送方可以发送一个 1 字节的数据报来通知接收方重新声明它希望接收的下一字节及发送方的滑动窗口大小。

拥塞控制

  • 拥塞控制和流量控制不同,前者是一个全局性的过程,而后者指点对点通信量的控制。在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫拥塞。

  • 拥塞控制就是为了防止过多的数据注入到网络中,这样就可以使网络中的路由器或链路不致于过载。拥塞控制所要做的都有一个前提,就是网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程,涉及到所有的主机,所有的路由器,以及与降低网络传输性能有关的所有因素。相反,流量控制往往是点对点通信量的控制,是个端到端的问题。流量控制所要做到的就是抑制发送端发送数据的速率,以便使接收端来得及接收。

  • 为了进行拥塞控制,TCP 发送方要维持一个拥塞窗口(cwnd) 的状态变量。拥塞控制窗口的大小取决于网络的拥塞程度,并且动态变化。发送方让自己的发送窗口取为拥塞窗口和接收方的接受窗口中较小的一个。

慢开始

  • 慢开始算法的思路是当主机开始发送数据时,如果立即把大量数据字节注入到网络,那么可能会引起网络阻塞,因为现在还不知道网络的符合情况。经验表明,较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是由小到大逐渐增大拥塞窗口数值。cwnd 初始值为 1,每经过一个传播轮次,cwnd 加倍。

拥塞避免

  • 到达慢开始阈值的时候,拥塞避免算法的思路是让拥塞窗口 cwnd 缓慢增大,即每经过一个往返时间 RTT 就把发送方的 cwnd 加 1。

  • 如果出现了超时,则令 ssthresh(慢开始阈值) = cwnd / 2,然后重新执行慢开始。

快重传

  • 在接收方,要求每次接收到报文段都应该对最后一个已收到的有序报文段进行确认。例如已经接收到 M1 和 M2,此时收到 M4,应当发送对 M2 的确认。

  • 在发送方,如果收到三个重复确认(3-ACK),那么可以知道下一个报文段丢失,此时执行快重传,立即重传下一个报文段。例如收到三个 M2,则 M3 丢失,立即重传 M3。

快恢复

  • 在这种情况下,只是丢失个别报文段,而不是网络拥塞。因此执行快恢复,令 ssthresh = cwnd / 2 ,cwnd = ssthresh,注意到此时直接进入拥塞避免。

http(post get)

区别

  • GET 只是一次 HTTP请求,POST 先发请求头再发请求体,实际上是两次请求。

  • 从功能上讲,GET 一般用来从服务器上获取资源,POST 一般用来更新服务器上的资源;

  • 从 REST 服务角度上说,GET 是幂等的,即读取同一个资源,总是得到相同的数据,而 POST 不是幂等的,因为每次请求对资源的改变并不是相同的;进一步地,GET 不会改变服务器上的资源,而 POST 会对服务器资源进行改变;

  • 从请求参数形式上看,GET 请求的数据会附在 URL 之后,即将请求数据放置在 HTTP 报文的 请求头 中,以 ? 分割 URL 和传输数据,参数之间以 & 相连。特别地,如果数据是英文字母/数字,原样发送;否则,会将其编码为 application/x-www-form-urlencoded MIME 字符串(如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用 BASE64 加密,得出如:%E4%BD%A0%E5%A5%BD,其中 %XX 中的 XX 为该符号以 16 进制表示的 ASCII);而 POST 请求会把提交的数据则放置在是 HTTP 请求报文的 请求体 中;

  • 就安全性而言,POST 的安全性要比 GET 的安全性高,因为 GET 请求提交的数据将明文出现在 URL 上,而且 POST 请求参数则被包装到请求体中,相对更安全;

  • 从请求的大小看,GET 请求的长度受限于浏览器或服务器对 URL 长度的限制,允许发送的数据量比较小,而 POST 请求则是没有大小限制的。