计算机网络是计算机、软工类面试的基础,不管是软件/硬件开发、技术支持还是测试职位,都会涉及到计算机网络的基础知识,本文基于笔者之前的面试准备所做的相关知识整理。本文的主要内容:
- OSI 与 TCP/IP 模型
- OSI 七层模型
- OSI 的缺陷
- TCP/IP 五层模型
- TCP 三次握手和四次挥手
- TCP 建立连接
- TCP三次握手,如果两次握手会怎么样?
- TCP 关闭连接
- 为什么建立连接是三次握手,而关闭连接却是四次挥手呢?
- 为什么需要 TIME_WAIT 状态?
- TCP 协议如何保证可靠传输
- HTTP 和 HTTPS
- 基本概念
- HTTPS 和 HTTP 的区别
- HTTP 响应的状态码
- HTTP 长连接、短连接
OSI 与 TCP/IP 模型
OSI 七层模型
OSI(Open System Interconnect),即开放式系统互联。 一般都叫OSI参考模型,是ISO(国际标准化组织)组织在1985年研究的网络互连模型。
OSI定义了网络互连的七层框架(物理层、数据链路层、网络层、传输层、会话层、表示层、应用层),即ISO开放互连系统参考模型。
从上到下介绍每层的功能:
- 应用层:OSI参考模型中最靠近用户的一层,是为计算机用户提供应用接口,也为用户直接提供各种网络服务。我们常见应用层的网络服务协议有:HTTP,HTTPS,FTP,POP3、SMTP等。
- 表示层:表示层提供各种用于应用层数据的编码和转换功能,确保一个系统的应用层发送的数据能被另一个系统的应用层识别。如果必要,该层可提供一种标准表示形式,用于将计算机内部的多种数据格式转换成通信中采用的标准表示形式。数据压缩和加密也是表示层可提供的转换功能之一。
- 会话层:负责建立、管理和终止表示层实体之间的通信会话。该层的通信由不同设备中的应用程序之间的服务请求和响应组成。
- 传输层:传输层建立了主机端到端的链接,传输层的作用是为上层协议提供端到端的可靠和透明的数据传输服务,包括处理差错控制和流量控制等问题。该层向高层屏蔽了下层数据通信的细节,使高层用户看到的只是在两个传输实体间的一条主机到主机的、可由用户控制和设定的、可靠的数据通路。我们通常说的,TCP UDP就是在这一层。端口号既是这里的“端”。
- 网络层:本层通过IP寻址来建立两个节点之间的连接,为源端的运输层送来的分组,选择合适的路由和交换节点,正确无误地按照地址传送给目的端的运输层。就是通常说的IP层。这一层就是我们经常说的IP协议层。IP协议是Internet的基础。
- 数据链路层:将比特组合成字节,再将字节组合成帧,使用链路层地址 (以太网使用MAC地址)来访问介质,并进行差错检测。数据链路层又分为2个子层:逻辑链路控制子层(LLC)和媒体访问控制子层(MAC)。
- MAC子层处理CSMA/CD算法、数据出错校验、成帧等;
- LLC子层定义了一些字段使上次协议能共享数据链路层。 在实际使用中,LLC子层并非必需的。
- 物理层
实际最终信号的传输是通过物理层实现的。通过物理介质传输比特流。规定了电平、速度和电缆针脚。常用设备有(各种物理设备)集线器、中继器、调制解调器、网线、双绞线、同轴电缆。这些都是物理层的传输介质。
OSI 的缺陷
OSI的七层体系结构概念清楚,理论也很完整,但是它比较复杂而且不实用。在这里顺带提一下之前一直被一些大公司甚至一些国家政府支持的OSI失败的原因:
- OSI的专家缺乏实际经验,他们在完成OSI标准时缺乏商业驱动力
- OSI的协议实现起来过分复杂,而且运行效率很低
- OSI制定标准的周期太长,因而使得按OSI标准生产的设备无法及时进入市场(20世纪90年代初期,虽然整套的OSI国际标准都已经制定出来,但基于TCP/IP的互联网已经抢先在全球相当大的范围成功运行了)
- OSI的层次划分不太合理,有些功能在多个层次中重复出现
TCP/IP 五层模型
TCP/IP五层协议和OSI的七层协议对应关系如下:
- 应用层(application layer)
应用层的任务是通过应用进程间的交互来完成特定网络应用。应用层协议定义的是应用进程(进程:主机中正在运行的程序)间的通信和交互的规则。对于不同的网络应用需要不同的应用层协议。在互联网中应用层协议很多,如域名系统DNS,支持万维网应用的HTTP协议,支持电子邮件的SMTP协议等等。我们把应用层交互的数据单元称为报文。 - 运输层(transport layer)
运输层的主要任务就是负责向两台主机进程之间的通信提供通用的数据传输服务。应用进程利用该服务传送应用层报文。“通用的”是指并不针对某一个特定的网络应用,而是多种应用可以使用同一个运输层服务。由于一台主机可同时运行多个线程,因此运输层有复用和分用的功能。所谓复用就是指多个应用层进程可同时使用下面运输层的服务,分用和复用相反,是运输层把收到的信息分别交付上面应用层中的相应进程。 运输层主要使用以下两种协议:- 传输控制协议TCP(Transmisson Control Protocol)--提供面向连接的,可靠的数据传输服务。
- 用户数据协议UDP(User Datagram Protocol)--提供无连接的,尽最大努力的数据传输服务(不保证数据传输的可靠性)。
- 网络层(network layer)
网络层负责为分组交换网上的不同主机提供通信服务。在发送数据时,网络层把运输层产生的报文段或用户数据报封装成分组和包进行传送。在TCP/IP体系结构中,由于网络层使用IP协议,因此分组也叫IP数据报,简称数据报。 这里要注意:不要把运输层的“用户数据报UDP”和网络层的“IP数据报”弄混。另外,无论是哪一层的数据单元,都可笼统地用“分组”来表示。 网络层的另一个任务就是选择合适的路由,使源主机运输层所传下来的分株,能通过网络层中的路由器找到目的主机。
互联网是由大量的异构(heterogeneous)网络通过路由器(router)相互连接起来的。互联网使用的网络层协议是无连接的网际协议(Intert Prococol)和许多路由选择协议,因此互联网的网络层也叫做网际层或IP层。 - 数据链路层(data link layer)
数据链路层通常简称为链路层。两台主机之间的数据传输,总是在一段一段的链路上传送的,这就需要使用专门的链路层的协议。 在两个相邻节点之间传送数据时,数据链路层将网络层交下来的IP数据报组装程帧,在两个相邻节点间的链路上传送帧。每一帧包括数据和必要的控制信息(如同步信息,地址信息,差错控制等)。 在接收数据时,控制信息使接收端能够知道一个帧从哪个比特开始和到哪个比特结束。这样,数据链路层在收到一个帧后,就可从中提出数据部分,上交给网络层。 控制信息还使接收端能够检测到所收到的帧中有误差错。如果发现差错,数据链路层就简单地丢弃这个出了差错的帧,以避免继续在网络中传送下去白白浪费网络资源。如果需要改正数据在链路层传输时出现差错(这就是说,数据链路层不仅要检错,而且还要纠错),那么就要采用可靠性传输协议来纠正出现的差错。这种方法会使链路层的协议复杂些。 - 物理层(physical layer)
在物理层上所传送的数据单位是比特。物理层的作用是实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异。使其上面的数据链路层不必考虑网络的具体传输介质是什么。“透明传送比特流”表示经实际电路传送后的比特流没有发生变化,对传送的比特流来说,这个电路好像是看不见的。
在互联网使用的各种协中最重要和最著名的就是TCP/IP两个协议。现在人们经常提到的TCP/IP并不一定单指TCP和IP这两个具体的协议,而往往表示互联网所使用的整个TCP/IP协议族。
TCP 三次握手和四次挥手
TCP创建过程和链接折除过程是由 TCP/IP 协议栈自动创建的。因此开发者并不需要控制这个过程,但是对于理解TCP底层运作机制,相当有帮助。
TCP 建立连接
TCP 建立连接,即所谓三次握手(Three-way Handshake),是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。具体过程如下:
- 客户端发送带有 SYN 标志的数据包–-一次握手–服务端;
- 服务端发送带有 SYN/ACK 标志的数据包–-二次握手–客户端;
- 客户端发送带有带有 ACK 标志的数据包–-三次握手–服务端。
TCP三次握手,如果两次握手会怎么样?
如果是两次握手,有这样一种情况,当 A 发送一个消息给 B,但是由于网络原因,消息被阻塞在了某个节点,然后阻塞的时间超出设定的时间,A 会认为这个消息丢失了,然后重新发送消息。当 A 和 B 通信完成后,这个被A认为失效的消息,到达了 B。
对于 B 而言,以为这是一个新的请求链接消息,就向 A 发送确认。对于 A 而言,它认为没有给 B 再次发送消息(因为上次的通话已经结束)所有 A 不会理睬 B 的这个确认,但是 B 则会一直等待 A 的消息。这就导致了 B 的时间被浪费(对于服务器而言,CPU 等资源是一种浪费),这样是不可行的,这就是为什么不能两次握手的原因了。
所以有了三次握手的修订,第三次握手看似多余其实不然,这主要是为了防止已失效的请求报文段突然又传送到了服务端而产生连接的误判。
TCP 关闭连接
TCP 连接的拆除需要发送四个包,因此称为四次挥手(four-way handshake)。客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作。
- 客户端发送一个 FIN,用来关闭客户端到服务器的数据传送;
- 服务器收到这个 FIN,它发回一个 ACK,确认序号为收到的序号加 1。和 SYN 一样,一个 FIN 将占用一个序号;
- 服务器关闭与客户端的连接,发送一个FIN给客户端;
- 客户端发回 ACK 报文确认,并将确认序号设置为收到序号加 1。
为什么建立连接是三次握手,而关闭连接却是四次挥手呢?
建立连接时,因为服务端在 LISTEN 状态下,收到建立连接请求的 SYN 报文后,把 ACK 和 SYN 放在一个报文里发送给客户端。
关闭连接时,当收到对方的 FIN 报文时,仅表示对方不再发送数据但还能接收收据,我们也未必把全部数据都发给了对方,所以我们可以立即 close,也可以发送一些数据给对方后,再发送 FIN 报文给对方表示同意关闭连接。因此我们的 ACK 和 FIN 一般会分开发送。
为什么需要 TIME_WAIT 状态?
从TCP连接关闭的状态转换关系可以看出,主动关闭的一方在发送完对对方 FIN 报文的确认(ACK)报文后,会进入 TIME_WAIT 状态。TIME_WAIT 状态也称为 2MSL 状态。
什么是2MSL?MSL 即 Maximum Segment Lifetime,也就是报文最大生存时间,引用《TCP/IP详解》中的话:它(MSL)是任何报文段被丢弃前在网络内的最长时间。那么,2MSL 也就是这个时间的 2 倍。最后总结为主动关闭的一方将继续等待一定时间(2-4分钟),使两端的应用程序结束。
为什么需要 TIME_WAIT 状态:
- 为实现 TCP 这种全双工连接的可靠释放
这样可让 TCP 再次发送最后的 ACK 以防这个 ACK 丢失(另一端超时并重发最后的 FIN)这种 2MSL 等待的另一个结果是这个 TCP 连接在 2MSL 等待期间,定义这个连接的插口(客户的 IP 地址和端口号,服务器的 IP 地址和端口号)不能再被使用。这个连接只能在 2MSL 结束后才能再被使用。 - 为使旧的数据包在网络因过期而消失
每个具体 TCP 实现必须选择一个报文段最大生存时间 MSL。它是任何报文段被丢弃前在网络内的最长时间。
TIME_WAIT 状态所带来的影响:
当某个连接的一端处于 TIME_WAIT 状态时,该连接将不能再被使用。事实上,对于我们比较有现实意义的是,这个端口将不能再被使用。某个端口处于 TIME_WAIT 状态(其实应该是这个连接)时,这意味着这个 TCP 连接并没有断开(完全断开),那么,如果你 bind 这个端口,就会失败。对于服务器而言,如果服务器突然 crash 掉了,那么它将无法再 2MSL 内重新启动,因为 bind 会失败。解决这个问题的一个方法就是设置 socket 的 SO_REUSEADDR 选项。这个选项意味着你可以重用一个地址。
TCP 协议如何保证可靠传输
TCP协议保证数据传输可靠性的方式主要有:
- 校验和: TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。
- 确认应答+序列号(累计确认+seq)。接收方收到报文就会确认(累积确认:对所有按序接收的数据的确认),TCP 给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。TCP 的接收端会丢弃重复的数据。
- 流量控制: TCP 连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制)
- 拥塞控制: 当网络拥塞时,减少数据的发送。
- 停止等待协议 也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。
- 超时重传: 当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。
HTTP 和 HTTPS
基本概念
HTTP:是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从 WWW 服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。
HTTPS:是以安全为目标的 HTTP 通道,简单讲是 HTTP 的安全版,即 HTTP 下加入 SSL 层,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL。 HTTPS协议的主要作用可以分为两种:一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性。
HTTPS 和 HTTP 的区别
- https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
- http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
- http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。
- http 的连接很简单,是无状态的;HTTPS 协议是由 SSL + HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 http 协议安全。
HTTP 响应的状态码
作为程序开发人员对于一些服务器返回的 HTTP 状态的意思都应该了如指掌,只有将这些状态码一一弄清楚,工作中遇到的各种问题才能够处理的得心应手。所以下面就让我们来了解一下比较常见的 HTTP 状态码吧!
-
1xx - 信息提示 这些状态代码表示临时的响应。客户端在收到常规响应之前,应准备接收一个或多个 1xx 响应。如:
- 100:Continue 初始的请求已经接受,客户应当继续发送请求的其余部分。(HTTP 1.1新)
- 101:Switching Protocols 服务器将遵从客户的请求转换到另外一种协议(HTTP 1.1 新)
-
2xx - 成功 这类状态代码表明服务器成功地接受了客户端请求。
- 200 - OK 一切正常,对GET和POST请求的应答文档跟在后面。 - 201 - Created 服务器已经创建了文档,Location头给出了它的URL。
- 202 - Accepted 已经接受请求,但处理尚未完成。
-
3xx - 重定向 客户端浏览器必须采取更多操作来实现请求。例如,浏览器可能不得不请求服务器上的不同的页面,或通过代理服务器重复该请求。如 304 Not Modified
-
4xx - 客户端错误 发生错误,客户端似乎有问题。例如,客户端请求不存在的页面,客户端未提供有效的身份验证信息。如:
- 400 - Bad Request 请求出现语法错误。
- 401 - Unauthorized 访问被拒绝,客户试图未经授权访问受密码保护的页面。
-
5xx - 服务器错误 服务器由于遇到错误而不能完成该请求。如:
- 500 - Internal Server Error 服务器遇到了意料不到的情况,不能完成客户的请求。
- 502 - Bad Gateway 服务器作为网关或者代理时,为了完成请求访问下一个服务器,但该服务器返回了非法的应答。
HTTP 长连接、短连接
在 HTTP/1.0 中默认使用短连接。也就是说,客户端和服务器每进行一次 HTTP 操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个 HTML 或其他类型的 Web 页中包含有其他的 Web 资源(如 JavaScript 文件、图像文件、CSS 文件等),每遇到这样一个 Web 资源,浏览器就会重新建立一个 HTTP 会话。 而从 HTTP/1.1 起,默认使用长连接,用以保持连接特性。使用长连接的 HTTP 协议,会在响应头加入这行代码:
Connection:keep-alive
复制代码
在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输 HTTP数据的 TCP 连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive 不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如 Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。