Loading...
墨滴

任冬学编程

2021/07/26  阅读:45  主题:极简黑

【面试系列】计算机网络(二)

此篇文章主要分享计算机网络中HTTP协议、HTTPS加密、socket网络编程等,文章如有不足之处,欢迎交流指出,【面试系列】会持续更新,敬请关注公众号“任冬学编程”!

公众号二维码
公众号二维码

1. HTTP协议

1.1、HTTP报文结构

HTTP请求报文

一个HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求数据4个部分组成

img
img

HTTP响应报文

HTTP响应也由三个部分组成,分别是:状态行、消息报头、响应正文

img
img

1.2、常见header

  • Host, 请求头

  • Accept-Encoding,请求头,可接受的文本压缩算法,如: gzip, deflate

  • Accept-Language,请求头,支持语言,客户端浏览器的设置,如:zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3

  • User-Agent,请求头,浏览器信息,如:Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:12.0) Gecko/20100101

  • Cookie,请求头,服务器或客户端在上次设置的COOKIE,包括作用域名(.360buy.com),过期时间,键与值。

  • Content-Type, 响应的数据类型:text/html;charset=gbk

  • Content-Length,响应的数据体大小

  • Content-Encoding, 如果为文本、HTML信息,则使用的编码方式

1.3、URL内容

URL(Uniform Resource Locator,统一资源定位符),URL由三部分组成:资源类型、存放资源的主机域名、资源文件名,URL的一般语法格式为:(带方括号[]的为可选项):

protocol://hostname[:port]/path/[;parameters][?query]#fragment

格式说明:

  1. protocol(协议):指定使用的传输协议, 最常用的是HTTP协议,它也是目前WWW中应用最广的协议。
  • ftp 通过 FTP访问资源。格式 ftp://

  • http 通过 HTTP 访问该资源。 格式 http://

  • https 通过安全的 HTTPS 访问该资源。 格式 https://

  1. hostname(主机名):是指存放资源的服务器的域名系统 (DNS) 主机名或 IP 地址。

  2. :port(端口号):整数,可选,省略时使用方案的默认端口,各种传输协议都有默认的端口号,如http的默认端口为80。如果输入时省略,则使用默认端口号。有时候出于安全或其他考虑,可以在服务器上对端口进行重定义,即采用非标准端口号,此时,URL中就不能省略端口号这一项。

  3. path(路径):由零或多个“/”符号隔开的字符串,一般用来表示主机上的一个目录或文件地址。

  4. ;parameters(参数):这是用于指定特殊参数的可选项。

  5. ?query(查询):可选,用于给动态网页(如使用CGI、ISAPI、PHP/JSP/ASP/ASP.NET等技术制作的网页)传递参数,可有多个参数,用“&”符号隔开,每个参数的名和值用“=”符号隔开。

  6. fragment(信息片断):字符串,用于指定网络资源中的片断。例如一个网页中有多个名词解释,可使用fragment直接定位到某一名词解释。

1.4、KeepAlive参数

  1. KeepAlive值是个布尔值,有两个值On和Off,简单来说,当值为On的时候,用户发起HTTP请求后,Apache不会立刻关闭这个连接,当还有用户发起HTTP请求时,还会使用这个连接,

  2. 什么时候关闭呢?看KeepAliveTimeout这个值,当时间达到KeepAliveTimeout这个值的时候才会关闭连接。当值为Off的时候,用户发起HTTP请求后,Apache会立刻关闭这个连接,缺点就是每次访问都要执行一次TCP握手,增加了CPU的开销。

1.5、状态码

  • 状态码200表示服务器响应成功,服务器找到了客户端请求的内容,并将内容发送给了客户端。
  • 状态码302表示临时跳转。
  • 状态码301代表的是永久性的重定向。
  • 304状态码,被请求的资源内容没有发生更改。
  • 401 (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。
  • 403 (禁止) 服务器拒绝请求。
  • 404 (未找到) 服务器找不到请求的网页。
  • 500 (服务器内部错误) 服务器遇到错误,无法完成请求。
  • 501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。
  • 502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
  • 503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。
  • 504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
  • 505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。

1.6、HTTP1.0/1.1/2.0 的区别

HTTP1.0最早在网页中使用是在1996年,那个时候只是使用一些较为简单的网页上和网络请求上,而HTTP1.1则在1999年才开始广泛应用于现在的各大浏览器网络请求中,同时HTTP1.1也是当前使用最为广泛的HTTP协议

HTTP 1.0

HTTP 1.0 是在 1996 年引入的,从那时开始,它的普及率就达到了惊人的效果。

  • HTTP 1.0 仅仅提供了最基本的认证,这时候用户名和密码还未经加密,因此很容易收到窥探。
  • HTTP 1.0 被设计用来使用短链接,即每次发送数据都会经过 TCP 的三次握手和四次挥手,效率比较低。
  • HTTP 1.0 只使用 header 中的 If-Modified-Since 和 Expires 作为缓存失效的标准。
  • HTTP 1.0 不支持断点续传,也就是说,每次都会传送全部的页面和数据。
  • HTTP 1.0 认为每台计算机只能绑定一个 IP,所以请求消息中的 URL 并没有传递主机名(hostname)。

HTTP 1.1

HTTP 1.1 是 HTTP 1.0 开发三年后出现的,也就是 1999 年,它做出了以下方面的变化

  • HTTP 1.1 使用了摘要算法来进行身份验证
  • HTTP 1.1 默认使用长连接,长连接就是只需一次建立就可以传输多次数据,传输完成后,只需要一次切断连接即可。长连接的连接时长可以通过请求头中的 keep-alive 来设置
  • HTTP 1.1 中新增加了 E-tag,If-Unmodified-Since, If-Match, If-None-Match 等缓存控制标头来控制缓存失效。
  • HTTP 1.1 支持断点续传,通过使用请求头中的 Range 来实现。
  • HTTP 1.1 使用了虚拟网络,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。

HTTP 2.0

HTTP 2.0 是 2015 年开发出来的标准,它主要做的改变如下

  • 头部压缩,由于 HTTP 1.1 经常会出现 User-Agent、Cookie、Accept、Server、Range 等字段可能会占用几百甚至几千字节,而 Body 却经常只有几十字节,所以导致头部偏重。HTTP 2.0 使用 HPACK 算法进行压缩。
  • 二进制格式,HTTP 2.0 使用了更加靠近 TCP/IP 的二进制格式,而抛弃了 ASCII 码,提升了解析效率
  • 强化安全,由于安全已经成为重中之重,所以 HTTP2.0 一般都跑在 HTTPS 上。
  • 多路复用,即每一个请求都是是用作连接共享。一个请求对应一个id,这样一个连接上可以有多个请求。

2. 客户端与服务器通信

2.1、通信模型

目前主流的网络通信模型有以下两种:

  1. 客户/服务器结构(Client/Server,缩写为C/S,胖客户):典型的C/S结构网络系统需要相应的客户端才能实现通信。目前大多数APP都是这种模式,如QQ、微博等。

  2. 浏览器/服务器结构(Browser/Server,缩写为B/S,瘦客户):典型的B/S结构网络系统只要通过浏览器即可访问,不需要在客户端机安装特定的软件。

2.2、通信方式

TCP通信

  1. 这种通信方式是实现C/S模式应用程序的主要方式。TCP是可靠的连接通信技术,主要使用套接字(Socket)。 Socket是TCP/IP协议中的传输层接口。TCP通信是使用TCP/IP协议、建立在稳定连接基础上的、以流传输数据的通信方式。

  2. TCP(Transfer Control Protocol)协议是一种面向连接的、提供可靠传输的协议。它可以确保接收方完全正确地接收到发送方所发送的全部数据。发送方和接收方之间的两个端口必须建立连接,以便在TCP协议的基础上进行通信。在程序中,端口之间建立连接一般使用Socket(套接字)方法。

  3. 当服务器的Socket等待服务器请求(即等待建立连接)时,客户机的Socket可以要求进行连接,一旦这两个Socket连接成功,它们就可以进行双向数据传输。TCP协议为实现可靠的数据传输提供了一个点对点的通道。

HTTP协议通信

​ 这种通信方式实现B/S模式应用程序的主要方式。HTTP协议简称超文本传输协议,它是应用层协议,主要解决如何包装数据,它建立在TCP/IP协议之上的一种应用,它是一种通用的、无状态的、面向对象的协议。 HTTP协议的作用原理包括四个步骤:

  1. 连接:Web浏览器与Web服务器建立连接。
  2. 请求:Web浏览器通过socket向Web服务器提交请求。HTTP的请求一般是GET或POST命令(POST用于FORM参数的传递)。
  3. 应答:Web浏览器提交请求后,通过HTTP协议传送给Web服务器。Web服务器接到后,进行事务处理,处理结果又通过HTTP传回给Web浏览器,从而在Web浏览器上显示出所请求的页面。
  4. 关闭连接:当应答结束后,Web浏览器与Web服务器必须断开,以保证其它Web浏览器能够与Web服务器建立连接。

3. HTTPS加密

3.1、加密过程

  1. 客户端请求服务器获取 证书公钥
  2. 客户端(SSL/TLS)解析证书(无效会弹出警告)
  3. 生成随机值
  4. 用 公钥加密 随机值生成密钥
  5. 客户端将 秘钥 发送给服务器
  6. 服务端用 私钥 解密 秘钥 得到随机值
  7. 将信息和随机值混合在一起 进行对称加密
  8. 加密的内容发送给客户端

3.2、中间人攻击

中间人的确无法得到浏览器生成的密钥B,这个密钥本身被公钥A加密了,只有服务器才有私钥A’解开拿到它呀!然而中间人却完全不需要拿到密钥A’就能干坏事了。请看:

  1. 某网站拥有用于非对称加密的公钥A、私钥A’。
  2. 浏览器向网站服务器请求,服务器把公钥A明文给传输浏览器。
  3. 中间人劫持到公钥A,保存下来,把数据包中的公钥A替换成自己伪造的公钥B(它当然也拥有公钥B对应的私钥B’)
  4. 浏览器随机生成一个用于对称加密的密钥X,用公钥B(浏览器不知道公钥被替换了)加密后传给服务器。
  5. 中间人劫持后用私钥B’解密得到密钥X,再用公钥A加密后传给服务器
  6. 服务器拿到后用私钥A’解密得到密钥X。

这样在双方都不会发现异常的情况下,中间人得到了密钥B。根本原因是浏览器无法确认自己收到的公钥是不是网站自己的

3.3、CA证书

CA证书是由CA(Certification Authority)认证机构发布的数字证书。其内容包含:电子签证机关的信息、公钥用户信息、公钥、签名和有效期。这里的公钥服务端的公钥,这里的签名是指:用hash散列函数计算公开的明文信息的信息摘要,然后采用CA的私钥对信息摘要进行加密,加密完的密文就是签名。 即:证书 = 公钥 + 签名 +申请者和颁发者的信息。 客户端中因为在操作系统中就预置了CA的公钥,所以支持解密签名(因为签名使用CA的私钥加密的)

SSL证书CA证书的一种,CA是负责签发证书、认证证书、管理已颁发证书的机关。 它制定政策和具体步骤来验证、识别用户身份,并对用户证书进行签名,以确保证书持有者的身份和公钥的拥有权。 SSL证书(http://ssl.idcspy.net/)就是CA机构签发的。 一般的CA证书,可以直接在WINDOWS上生成。

  1. SSL证书,用于加密HTTP协议,也就是HTTPS。

  2. 代码签名证书,用于签名二进制文件,比如Windows内核驱动,Firefox插件,Java代码签名等等。

  3. 客户端证书,用于加密邮件。

  4. 双因素证书,网银专业版使用的USB Key里面用的就是这种类型的证书。

网站在使用HTTPS前,需要向“CA机构”申请颁发一份数字证书数字证书里有证书持有者、证书持有者的公钥等信息,服务器把证书传输给浏览器,浏览器从证书里取公钥就行了,证书就如身份证一样,可以证明“该公钥对应该网站”。然而这里又有一个显而易见的问题了,证书本身的传输过程中,如何防止被篡改?即如何证明证书本身的真实性?身份证有一些防伪技术,数字证书怎么防伪呢?

3.4、数字签名

我们把证书内容生成一份“签名”,比对证书内容和签名是否一致就能察觉是否被篡改。这种技术就叫数字签名。

数字签名制作过程:

  1. CA拥有非对称加密的私钥和公钥。
  2. CA对证书明文信息进行hash。
  3. 对hash后的值用私钥加密,得到数字签名。

明文和数字签名共同组成了数字证书,这样一份数字证书就可以颁发给网站了。那浏览器拿到服务器传来的数字证书后,如何验证它是不是真的?(有没有被篡改、掉包)

浏览器验证过程:

  1. 拿到证书,得到明文T,数字签名S。
  2. 用CA机构的公钥对S解密(由于是浏览器信任的机构,所以浏览器保有它的公钥。详情见下文),得到S’。
  3. 用证书里说明的hash算法对明文T进行hash得到T’。
  4. 比较S’是否等于T’,等于则表明证书可信。

4. Session、Cookie & Token

4.1、cookie

  1. HTTP协议本身是无状态的。什么是无状态呢,即服务器无法判断用户身份。

  2. **cookie是由Web服务器保存在用户浏览器上的小文件(key-value格式),包含用户相关的信息。**客户端向服务器发起请求,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户身份。

4.2、session

  1. session是依赖Cookie实现的。session是服务器端对象session 是浏览器和服务器会话过程中,服务器分配的一块储存空间。服务器默认为浏览器在cookie中设置 sessionid,浏览器在向服务器请求过程中传输 cookie 包含 sessionid ,服务器根据 sessionid 获取出会话中存储的信息,然后确定会话的身份信息。
  2. 典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了。

cookie与session区别

  • 存储位置与安全性:cookie数据存放在客户端上,安全性较差,session数据放在服务器上,安全性相对更高;
  • 存储空间:单个cookie保存的数据不能超过4K,**很多浏览器都限制一个站点最多保存20个cookie,**session无此限制
  • 占用服务器资源:session一定时间内保存在服务器上,当访问增多,占用服务器性能,考虑到服务器性能方面,应当使用cookie。

4.3、Token

Token的引入:Token是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示,在这样的背景下,Token便应运而生。

Token的定义:Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。

使用Token的目的:Token的目的是为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮

Token 是在服务端产生的。如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端。前端可以在每次请求的时候带上 Token 证明自己的合法地位

session与token区别

  • session机制存在服务器压力增大,CSRF跨站伪造请求攻击,扩展性不强等问题;
  • session存储在服务器端,token存储在客户端
  • token提供认证和授权功能,作为身份认证,token安全性比session好;
  • session这种会话存储方式方式只适用于客户端代码和服务端代码运行在同一台服务器上,token适用于项目级的前后端分离(前后端代码运行在不同的服务器下)

5. socket网络编程

5.1、socket套接字

  1. Socket的英文原义是“孔”或“插座”。作为BSD UNIX的进程通信机制,取后一种意思。通常也称作”套接字”,用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。

  2. 将传输层及以下的网络协议封装,提供简单使用的接口(API)给应用层的软件,专门面向C/S架构模型设计的

  3. 三元组:IP地址、协议、端口号

网络层的“ip地址”可以唯一标识网络中的主机,而传输层的“协议+端口”可以唯一标识主机中的应用程序(进程)。这样利用三元组(ip地址,协议,端口)就可以标识网络的进程了,网络中的进程通信就可以利用这个标志与其它进程进行交互。

5.2、套接字的连接过程

  1. 服务器监听不指定具体的客户端套接字,处于等待连接的状态,实时监控网络状态
  2. 客户端请求:指由客户端的套接字提出请求,目标是服务器端的套接字,需要指出服务器端套接字的地址和端口号
  3. 连接确认:当服务器端套接字监听到客户端套接字的连接请求,就响应请求建立一个新的进程并返回客户端服务器的套接字描述,当客户端确认描述,连接就正式建立,服务器端继续处于监听状态

5.3、套接字(socket)函数

服务端

  • s.bind()
    • 绑定(主机,端口号)到套接字
  • s.listen()
    • 开始TCP监听
    • 必须制定最大连接数(操作系统同时能够链接的最大数目)
  • s.accept()
    • 被动接受TCP客户的连接,(阻塞式)等待连接到来(阻塞:无响应直到接受到连接请求)

客户端

  • s.connect()
    • 主动初始化TCP服务器连接
  • s.connec_ex()
    • connect()函数的扩展版本,出错时返回出错码,不抛出异常

公共用途

  • s.recv()
    • 接收TCP数据
    • 不可接收’空’
  • s.send()
    • 发送TCP数据
    • 待发送数量大于己端缓存剩余区空间时,数据丢失,不会发完
  • s.sendall()
    • 发送完整的TCP数据,循环调用s.send
    • 通常给数据加上报头将数据打包更安全可靠,不常用sendall
  • s.recvfrom()
    • 接收UDP数据
  • s.sendto()
    • 发送UDP数据
  • s.getpeername()
    • 连接到当前套接字的远端的地址
  • s.getsockname()
    • 当前套接字的地址
  • s.getsockopt()
    • 返回指定套接字的参数
  • s.setsockopt()
    • 设置指定套接字的参数
  • s.close()
    • 关闭套接字

面向锁的套接字方法

  • s.setblocking()
    • 设置套接字的阻塞与非阻塞模式
  • s.settimeout()
    • 设置阻塞套接字操作的超时时间
  • s.gettimeout()
    • 得到阻塞套接字操作的超时时间

面向文件的套接字的函数

  • s.fileno()
    • 套接字的文件描述符
  • s.makefile()
    • 创建一个与该套接字相关的文件

【面试系列】文章会持续更新,欢迎关注公众号“任冬学编程”,听说点赞都能脱单哦!

- END -

任冬学编程

2021/07/26  阅读:45  主题:极简黑

作者介绍

任冬学编程

微信公众号:任冬学编程