网络编程原理

网络编程原理

一、DNS:

构成互联网 Internet 的最基本的网络协议就是互联网协议 InternetProtocol,简称 IP 协议。IP 地址就是互联网的地址标识。

那么手机上的App如何知道数据中心服务器的IP地址呢?开发工程师可以在App里将这个IP地址固定写,但是这样做会带来很多问题,比如会影响程序的可用性等。

事实上这个IP地址是通过DNS域名解析服务器得到的。当我们打开一个App的时候,App应用加载页面的时候,这时候需要连接域名服务器进行域名解析,将 www.taobao.com 这样的一个域名解析为一个IP地址,然后连接目标服务器。

二、CDN:

CDN 是内容分发网络 Content Delivery Network 的缩写

我们能够用手机或电脑上网,是因为运营服务商为我们提供了互联网接入服务,将我们的手机和电脑连接到互联网上。

App请求的数据最先达到的是运营服务商的机房,然后运营服务商通过自己搭建的骨干网络和交换节点,将我们请求数据的目的地址发往互联网任何地方。

为了提高用户请求访问的速度,也为了降低数据中心的负载压力,淘宝会在全国各地各个主要的运营服务商的接入机房中部署一些缓存服务器,缓存那些静态的图片、资源文件等,这些缓存服务器构成了淘宝的 CDN。

如果用户请求的数据是静态资源,这些资源的 URL 通常以 image.taobao.com 之类的二级域名进行标识,域名解析的时候就会解析为淘宝 CDN 的 IP 地址,请求先被 CDN 处理,如果 CDN 中有需要的静态文件,就直接返回,如果没有,CDN 会将请求发送到淘宝的数据中心,CDN 从淘宝数据中心获得静态文件后,一方面缓存在自己的服务器上,一方面将数据返回给用户的 App。

三、HTTP:

1.简介:

HTTP协议即超文本传输协议(HyperText Transfer Protocol)服务器传输超文本到本地浏览器的传送协议。HTTP是一个基于TCP/IP通信协议来传递数据。

HTTP是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。HTTP是一个应用层协议

在 TCP 传输层协议层面,就是保证建立通信两方的稳定通信连接,将一方的数据以 bit 流的方式源源不断地发送到另一方,至于这些数据代表什么意思,哪里是两次请求的分界点,TCP 协议统统不管,需要应用层面自己解决。而互联网应用需要在全球范围为用户提供服务,将全球的应用和全球的用户联系在一起,需要一个统一的应用层协议,这个协议就是 HTTP 协议。

2.主要特点:

  1. 简单快速:向服务器请求服务时,只需传送请求方法和路径。 HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
  2. 灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
  3. 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
  4. 无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。

3.URL:

HTTP使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。

http://www.51easymaster.com:8080/course/index?courseID=1&userID=24618&page=1#name
  1. 协议部分:该URL的协议部分为“http:”,这代表网页使用的是HTTP协议。

    在Internet中可以使用多种协议,如HTTP,HTTPS,FTP等等本例中使用的是HTTP协议。在"HTTP"后面的“//”为分隔符;

  2. 域名部分:该URL的域名部分为"www.51easymaster.com"。一个URL中,也可以使用IP地址作为域名使用。

  3. 端口部分:跟在域名后面的是端口,域名和端口之间使用" : "作为分隔符。

    端口不是一个URL必须的部分,如果省略端口部分,将采用默认端口; 本栗子端口是8080

  4. 虚拟目录部分:从域名后的第一个" / " 开始到最后一个" / "为止,是虚拟目录部分。

    虚拟目录也不是一个URL必须的部分。本例中的虚拟目录是"/course/"

  5. 文件名部分:从域名后的最后一个" / " 开始到 " ? " 为止,是文件名部分。

    如果没有" ? “,则是从域名后的最后一个” / "开始到“#”为止,是文件部分;

    如果没有" ? “和” # “,那么从域名后的最后一个” / " 开始到结束,都是文件名部分;

    本栗子文件名是"index"。文件名部分也不是一个URL必须的部分;

  6. 锚部分:从" # "开始到最后,都是锚部分。

    锚部分也不是一个URL必须的部分;

    本栗子锚的部分是"name"

  7. 参数部分:从" ? “开始到” # "为止之间的部分为参数部分,又称搜索部分、查询部分。

    本栗子的参数部分为"courseID=1&userID=24618&page=1"。

    参数可以允许有多个参数,参数与参数之间用" & " 作为分隔符

4.Request请求:

客户端发送一个HTTP请求到服务器的请求消息包括以下格式:

  1. 请求行(request line);
  2. 请求头部(header);
  3. 空行;
  4. 请求数据;
GET /image.jpg HTTP/1.1
Host    img.taobao.com
User-Agent    Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/32.36 (KHTML, like Gecko) Chrome/183.0.2704.106 Safari/32.36
Accept    image/webp,image/*,*/*;q=0.8
Referer    http://www.baidu.com/
Accept-Encoding    gzip, deflate, sdch
Accept-Language    zh-CN,zh;q=0.8

第一部分:请求行,用来说明请求类型,要访问的资源以及所使用的HTTP版本。

GET:说明是GET请求类型;

/image.jpg:要访问的资源,

HTTP /1.1 :版本号

第二部分:请求头部,用来说明服务器要使用的附加信息。

Accept:浏览器可接受的MIME类型;

Accept - Charset:浏览器可接受的字符集;

Accept - Encoding:浏览器能够进行解码的数据编码方式,比如gzip;

Accept - Language:浏览器所希望的语言种类,当服务器能够提供一种以上的语言版本时要用到;

Authorization:授权信息,通常出现在对服务器发送的WWW - Authenticate头的应答中;

Connection:表示是否需要持久连接;

Content - Length:表示请求消息正文的长度;

Cookie:当前页面设置的任何Cookie;

Host:初始URL中的主机和端口;

Pragma:指定“no - cache”值表示服务器必须返回一个刷新后的文档,即使它是代理服务器而且已经有了页面的本地拷贝。

Referer:包含一个URL,用户从该URL代表的页面出发访问当前请求的页面;

User - Agent:浏览器类型,如果Servlet返回的内容与浏览器类型有关则该值非常有用;

UA - Pixels,UA - Color,UA - OS,UA - CPU:由某些版本的IE浏览器所发送的非标准的请求头,表示屏幕大小、颜色深度、操作系统和CPU类型。

第三部分:空行

即使第四部分的请求数据为空,也必须有空行;

第四部分:请求主体,可以添加任意其他数据;

此栗子请求主体为空;

请求方法主要有:GET、POST、HEAD、PUT、DELETE、CONNECT、OPTIONS、TRACE。

  1. GET:请求指定的页面信息,并返回实体主体;
  2. POST:向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中,POST请求可能会导致新的资源的建立和/或已有资源的修改;
  3. HEAD:类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头;
  4. PUT:从客户端向服务器传送的数据取代指定的文档的内容;
  5. DELETE:请求服务器删除指定的页面;
  6. CONNECT:HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器;
  7. OPTIONS:允许客户端查看服务器的性能;
  8. TRACE: 回显服务器收到的请求,主要用于测试或诊断;

5.Response响应:

一般情况下,服务器接收并处理客户端发过来的请求后会返回一个HTTP的响应消息。

HTTP响应也是由四个部分组成:

  1. 状态行;
  2. 消息报头;
  3. 空行;
  4. 响应正文;
HTTP/1.1 200 OK
Date: Fri, 26 May 2019 16:07:21 GMT
Content-Type: text/html; charset=UTF-8

<html>
      <head></head>
      <body>
            <!--fe_cow-->
      </body>
</html>

第一部分:状态行,由HTTP协议版本号,状态码,状态消息三部分组成;

HTTP/1.1 :协议版本号;

200:状态码;

OK:状态消息"OK"

第二部分:消息报头,用来说明客户端要使用的一些附加信息

Date:生成响应的日期喝时间;
Content-Type: 指定 MIME类型的 HTML(text/html),编码类型是UTF-8;

第三部分:空行

消息报头后面的空行是必须有;

第四部分:响应正文,服务器返回给客户端的文本信息

>  < html>
>        < head></head>
>        < body>
>              <!--fe_cow-->
>        </body>
>  </html>

响应状态码

  1. 状态码是 200,表示响应正常。

  2. 响应状态码是 3XX,表示请求被重定向。

    301:代表永久性转移;

    302:表示请求被临时重定向到新的 URL,响应头中包含新的临时 URL,客户端收到响应后,重新请求这个新的 URL;

  3. 状态码是 4XX,表示客户端错误。

    401:是没有带认证信息或者带了错误的认证信息, 这时客户端可以修改认证信息进行重试 ;

    403:客户端带了正确的认证信息, 但服务器认为这个认证信息对应的用户是没有对应资源的访问权限的;

    404:表示请求的页面不存在;

  4. 状态码是 5XX,表示服务器异常。

    500:请求未完成;

    502:请求处理超时;

    503:服务器过载;

如果响应正常,那么在响应头之后就是响应 body,浏览器的响应 body 通常是一个 HTML 页面,App 的响应 body 通常是个 JSON 字符串。

6.HTTP工作原理:

以下是HTTP请求/响应的步骤:
  1. 客户端连接Web服务器

    • 一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。

      比如 http:www.taobao.com

  2. 发送HTTP请求

    • 通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据4部分组成。
  3. 服务器接受请求并返回HTTP响应

    • Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成。
  4. 释放连接TCP连接

    • 若connection 模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求;
  5. 客户端浏览器解析HTML内容

    1. 客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。
    2. 然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。
    3. 客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。
浏览器地址栏输入URL地址,按回车会经历的以下流程:
  1. 浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;
  2. 解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器建立TCP 连接;
  3. 浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求,该请求报文作为 TCP 三次握手 的第三个报文的数据发送给服务器;
  4. 服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器;
  5. 释放TCP连接;
  6. 浏览器将该 html 文本并显示内容;

7.GET请求与POST请求的区别:

  1. GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连。POST方法是把提交的数据放在HTTP包的Body中

    index?courseID=1&userID=24618&page=1

  2. GET提交的数据大小有限制(因为浏览器对URL的长度有限制),而POST方法提交的数据没有限制

  3. GET方式需要使用Request.QueryString来取得变量的值,而POST方式通过Request.Form来获取变量的值。

  4. GET方式提交数据,会带来安全问题

    比如一个登录页面,通过GET方式提交数据时,用户名和密码将出现在URL上,如果页面可以被缓存或者其他人可以访问这台机器,就可以从历史记录获得该用户的账号和密码;

四、TCP:

应用程序使用操作系统的 socket 接口进行网络编程,socket 里封装了 TCP 协议。应用程序通过 socket 接口使用 TCP 协议完成网络编程,socket 或者 TCP 在应用程序看就是一个底层通信协议,事实上,TCP 仅仅是一个传输层协议

传输层协议 TCP 和网络层协议 IP 共同构成 TCP/IP 协议栈,成为互联网应用开发最主要的通信协议。

OSI 开放系统互联模型将网络协议定义了 7 层,TCP/IP 协议栈将 OSI 顶部三层协议应用层、表示层、会话层合并为一个应用层,HTTP 协议就是 TCP/IP 协议栈中的应用层协议。

开放系统互连参考模型 (Open System Interconnect 简称OSI)是国际标准化组织(ISO)和国际电报电话咨询委员会(CCITT)联合制定的开放系统互连参考模型,为开放式互连信息系统提供了一种功能结构的框架。

  1. 应用层:提供网络与用户应用软件之间的接口服务;
  2. 表示层:提供格式化的表示和转换数据服务,如加密和压缩;
  3. 会话层:提供包括访问验证和会话管理在内的建立和维护应用之间通信的机制;
  4. 传输层:提供建立、维护和取消传输连接功能,负责可靠地传输数据,TCP连接;
  5. 网络层:网络层的数据需要交给链路层进行处理,而链路层帧的大小定义了最大传输单元,网络层的 IP 数据包必须要小于最大传输单元才能进行网络传输,这个数据包也有一个 IP 头,主要包括的就是发送者和接受者的 IP 地址。
  6. 数据链路层:就是将数据进行封装后交给物理层进行传输,主要就是将数据封装成数据帧,以帧为单位通过物理层进行通信,有了帧,就可以在帧上进行数据校验,进行流量控制。数据链路层会定义帧的大小,这个大小也被称为最大传输单元。
  7. 物理层:负责数据的物理传输,计算机输入输出的只能是 0 1 这样的二进制数据,但是在真正的通信线路里有光纤、电缆、无线各种设备。光信号和电信号,以及无线电磁信号在物理上是完全不同的,如何让这些不同的设备能够理解、处理相同的二进制数据,这就是物理层要解决的问题。

1.TCP 三次握手和四次挥手:

注意:专业述语

ack —— 确认号码

seq —— 顺序号码

ISN —— 初始序列号

ACK —— 确认,使得确认号有效 (握手使用)

SYN —— 用于初始化一个连接的序列号,建立连接

Seq —— 表示请求建立连接

FIN —— 该报文的发送方已经结束向对方发送数据

三次握手,实际就是客户端 和 服务器 建立稳定TCP 连接的 发送三个包的过程

第一次握手:(SYN=1,Seq=X)

App 先发送 SYN=1,Seq=X 的报文,表示请求建立连接,X 是一个随机数;

第二次握手:(SYN=1,ACK=X+1,Seq=Y)

服务器收到这个报文后,应答 SYN=1,ACK=X+1,Seq=Y 的报文,表示同意建立连接;

第三次握手:(ACK=Y+1,Seq=Z)

App 收到这个报文后,检查 ACK 的值为自己发送的 Seq 值 +1,确认建立连接,并发送 ACK=Y+1 的报文给服务器;服务器收到这个报文后检查 ACK 值为自己发送的 Seq 值 +1,确认建立连接。至此,App 和服务器建立起 TCP 连接,就可以进行数据传输了。

举个形象的栗子,有A(客户端) 和 B(服务器) 想进行通话:

  • A 先对 B 说:“喂,你在么?我在的,我的口令是 “x”。
  • B 收到之后大声回答:“我收到你的口令 “x” 并准备好了,你准备好了吗?我的口令是 “y”。
  • ”A 收到之后也大声回答:“我收到你的口令 “y” 并准备好了,我们开始吧。

TCP建立一个连接需3次握手,而终止一个连接则需要四次挥手

  1. 一方应用程序调用 close,我们称该方为主动关闭方,该端的 TCP 发送一个 FIN 包,表示需要关闭连接。

    之后主动关闭方进入 FIN_WAIT_1 状态;

  2. FIN 包的对端执行被动关闭。这个 FIN 由 TCP 协议栈处理。

    我们知道,TCP 协议栈为 FIN 包插入一个文件结束符 EOF 到接收缓冲区中,应用程序可以通过 read 调用来感知这个 FIN 包;

    这个 EOF 会被放在已排队等候的其他已接收的数据之后,这就意味着接收端应用程序需要处理这种异常情况,因为 EOF 表示在该连接上再无额外数据到达;

    被动关闭方进入 CLOSE_WAIT 状态;

  3. 接下来,被动关闭方将读到这个 EOF,应用程序也调用 close 关闭它的套接字,这导致它的 TCP 也发送一个 FIN 包。

    被动关闭方将进入 LAST_ACK 状态;

  4. 主动关闭方接收到对方的 FIN 包,并确认这个 FIN 包。

    主动关闭方进入 TIME_WAIT 状态,而接收到 ACK 的被动关闭方则进入 CLOSED 状态。进过 2MSL 时间之后,主动关闭方也进入 CLOSED 状态;

每个方向都需要一个FIN 和 一个ACK ,因此通常被称为 四次挥手

五、一个字符的发送处理:

如果我们以POST方法提交一个搜索请求给淘宝服务器,那么最终在数据链路层构建出来的数据帧大概是这样的。

  1. APP 要发送的数据只是 key = “a”,这样一个JSON 字符串,每一层协议都会在上一层协议基础上添加一个头部信息,最后封装成一个链路层的数据帧在网络上传输,发送给淘宝服务器。
  2. 淘宝的服务器在收到这个数据帧后,在通信协议的每一层进行校验检查,确保数据准确后,将头部信息删除,再交给自己的上一层协议处理。
  3. HTTP 应用服务器在最上层,负责 HTTP 协议的处理,最后将 key=“a”这个 JSON 字符串交给淘宝工程师开发的应用程序处理。

参考资料:

《后端技术基础38讲》

《网络编程实战》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章