zoukankan      html  css  js  c++  java
  • 网络通信必备基础之Http协议&TCP/IP协议(二)

    阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680
    本篇文章将继续从以下两个内容来介绍网络通信必备基础:

    • [Http协议]
    • [TCP/IP协议]

    一、Http协议

    当你在浏览器地址栏敲入“http://www.jianshu.com/”,然后猛按回车,呈现在你面前的,将是简书的首页了(这真是废话,你会认为这是理所当然的)。作为一个开发者,尤其是web开发人员,我想你有必要去了解这一系列的处理流程,在这期间,浏览器和服务器到底是如何打交道的?服务器又是如何处理的?浏览器又是如何将网页显示给用户的呢?......

    疑惑和细节真是太多了。坦白讲,要想彻彻底底的弄清楚以上每个疑惑和处理细节,至少需要十本书的厚度,所谓“底层无极限”嘛,而且不同的web服务 器和服务器端编程语言的实现和处理流程不尽相同(但本质都是相通的)。本文中,我将根据http协议的有关知识,跟大家讲解一些web开发的本质。不管你 是从事.NET,还是J2EE或者php开发等等,都离不开这些本质。希望你读完本文,能有新的收获和见解。由于本人水平和经验有限,难免有误,望读者见 谅。

    何为http协议(Hypertext Transfer Protocol,超文本传输协议)?

    所谓协议,就是指双方遵循的规范。http协议,就是浏览器和服务器之间进行“沟通”的一种规范。我们在看空间,刷微博...都是在使用http协议,当然,远远不止这些应用。

    笔者一直听说http是属于“应用层的协议”,而且是基于TCP/IP协议的。这个不难理解,如果你上大学时候学过“计算机网络”的课程,就一定知 道OSI七层参考协议(我当时是死记硬背的)。如果你接触过socket网络编程,就应该明白TCP和UDP这两种使用广泛的通信协议(建立连接、三次握 手等等,当然,这不是本文讨论的重点)。如图:

     
    19956127-cc33de5460e5a4e2.png
     


    既然TCP/UDP是广泛使用的网络通信协议,那为啥有多出个http协议来呢?

    笔者曾自己动手写过一个简单的web服务器处理软件,根据我的推断(不一定准确)。UDP协议具有不可靠性和不安全性,显然这很难满足web应用的需要。

    而TCP协议是基于连接和三次握手的,虽然具有可靠性,但人具有一定的缺陷。但试想一下,普通的C/S架构软件,顶多上千个Client同时连接,而B/S架构的网站,十万人同时在线也是很平常的事儿。如果十万个客户端和服务器一直保持连接状态,那服务器如何满足承载呢?

    这就衍生出了http协议。基于TCP的可靠性连接。通俗点说,就是在请求之后,服务器端立即关闭连接、释放资源。这样既保证了资源可用,也吸取了TCP的可靠性的优点。

    正因为这点,所以大家通常说http协议是“无状态”的,也就是“服务器不知道你客户端干了啥”,其实很大程度上是基于性能考虑的。以至于后来有了session之类的玩意。

    实战准备工作:

    在监视网络方面,windows平台上有一款叫做Sniffer的优秀软件,这也是很多“黑客”经常使用的嗅探工具。 在研究http协议时,推荐大家使用一款

    叫作httpwatch的工具。(遗憾的是,该工具是收费的。该咋办就咋办,你懂的)。安装完成后,可以在IE浏览器的tools中直接打开(目前也支持firefox)。如图所示:

     
    19956127-d7db0fac07ded6dc.png
     


    点击Record,就可以开始监视并记录http消息了。stop、Clear等等按钮的功能,这里就不一一介绍了。拿实例来说话,下面就是我记录访问main.aspx页面的时候记录的,能够清晰的看到http报文消息的详细信息,如图:

     
    19956127-4aa18767a8a8c699.png
     


    学习http协议,主要需要了解http的请求和响应(当然,还有get、post等请求方式,状态码、URI、MIME等)

    首先看看http请求消息(就是浏览器丢给服务器的):

    一个http请求代表客户端浏览器向服务器发送的数据。一个完整的http请求消息,包含一个请求行,若干个消息头(请求头),换行,实体内容

    请求行:描述客户端的请求方式、请求资源的名称、http协议的版本号。 例如: GET/BOOK/JAVA.HTML HTTP/1.1

    请求头(消息头)包含(客户机请求的服务器主机名,客户机的环境信息等):
    Accept:用于告诉服务器,客户机支持的数据类型 (例如:Accept:text/html,image/*)
    Accept-Charset:用于告诉服务器,客户机采用的编码格式
    Accept-Encoding:用于告诉服务器,客户机支持的数据压缩格式
    Accept-Language:客户机语言环境
    Host:客户机通过这个服务器,想访问的主机名
    If-Modified-Since:客户机通过这个头告诉服务器,资源的缓存时间
    Referer:客户机通过这个头告诉服务器,它(客户端)是从哪个资源来访问服务器的(防盗链)
    User-Agent:客户机通过这个头告诉服务器,客户机的软件环境(操作系统,浏览器版本等)
    Cookie:客户机通过这个头,将Coockie信息带给服务器
    Connection:告诉服务器,请求完成后,是否保持连接
    Date:告诉服务器,当前请求的时间

    (换行)
    实体内容:
    就是指浏览器端通过http协议发送给服务器的实体数据。例如:name=dylan&id=110
    (get请求时,通过url传给服务器的值。post请求时,通过表单发送给服务器的值)

    再看看HTTP响应消息(服务器返回给浏览器的):

    一个http响应代表服务器端向客户端回送的数据,它包括:
    一个状态行,若干个消息头,以及实体内容

    响应头(消息头)包含:
    Location:这个头配合302状态吗,用于告诉客户端找谁
    Server:服务器通过这个头,告诉浏览器服务器的类型
    Content-Encoding:告诉浏览器,服务器的数据压缩格式
    Content-Length:告诉浏览器,回送数据的长度
    Content-Type:告诉浏览器,回送数据的类型
    Last-Modified:告诉浏览器当前资源缓存时间
    Refresh:告诉浏览器,隔多长时间刷新
    Content-Disposition:告诉浏览器以下载的方式打开数据。例如: context.Response.AddHeader("Content-Disposition","attachment:filename=aa.jpg"); context.Response.WriteFile("aa.jpg");
    Transfer-Encoding:告诉浏览器,传送数据的编码格式
    ETag:缓存相关的头(可以做到实时更新)
    Expries:告诉浏览器回送的资源缓存多长时间。如果是-1或者0,表示不缓存
    Cache-Control:控制浏览器不要缓存数据 no-cache
    Pragma:控制浏览器不要缓存数据 no-cache

    Connection:响应完成后,是否断开连接。 close/Keep-Alive
    Date:告诉浏览器,服务器响应时间

    状态行: 例如: HTTP/1.1 200 OK (协议的版本号是1.1 响应状态码为200 响应结果为 OK)

    实体内容(实体头):响应包含浏览器能够解析的静态内容,例如:html,纯文本,图片等等信息

    理解了以上的http请求消息和响应消息,相信你对于http协议已经理解得足够深刻了。关于http协议的更多具体细节,可以参照http RFC文档

    大致步骤就是:浏览器先向服务器发送请求,服务器接收到请求后,做相应的处理,然后封装好响应报文,再回送给浏览器。浏览器拿到响应报文后,再通过 浏览器引擎去渲染网页,解析DOM树,javascript引擎解析并执行脚本操作,插件去干插件该干的事儿...关于浏览器渲染、解析的原理,可以参考http://kb.cnblogs.com/page/129756/

    说白了,所谓web的本质,无非是:请求/处理/响应 ,任何的web服务器,任何的服务端编程语言,都没法脱离这个本质。 而浏览器端解析html、图片等静态内容,呈现给用户,脚本引擎执行脚本代码,完成脚本代码要做的事儿(例如dom操作,css属性更改,发送ajax请 求等等)。

    二、TCP/IP协议详解

    2.1 什么是协议?

    简单来说,协议就是计算机之间通过网络实现通信时事先达成的一种“约定”;这种“约定”使那些由不同厂商的设备,不同CPU及不同操作系统组成的计算机之间,只要遵循相同的协议就可以实现通信。TCP/IP通常被认为是一个四层协议,如图:

     
    13566833-2c72498c79afe2dc.png
     

    链路层:数据链路层或网络接口层,包括设备驱动程序和网络接口卡,它们一起处理与电缆的物理接口细节。
    网络层:处理分组在网络中的活动,如分组的选路;网络层的协议包括IP协议、ICMP协议(Internet互联网控制报文协议)、IGMP协议(Internet组管理协议)。
    传输层:主要为两台主机上的应用程序提供端到端的通信,包括TCP(传输控制协议)和UDP(用户数据报协议)。
    应用层:处理特定的应用程序细节。

     
    13566833-911c38a77ac6d360.png
     

    链路层的三个主要作用:
    1)为IP模块发送和接受IP数据;
    2)为ARP模块发送ARP请求和接受ARP应答;
    3)为RARP发送RARP请求和接受RARP应答。


    TCP创建过程和链接折除过程是由TCP/IP协议栈自动创建的,所以开发者并不需要理解得十分透彻,只需要对TCP底层运作机制有一个大致理解即可,这一块有些复杂,先做个笔记,以后有需要,再做详细扩展


    拓展:检测网络是否联通的命令——Ping
    Ping的目的是为了测试另一台主机是否可达,该命令会发送一份ICMP回显请求报文给主机,并等待返回ICMP回显应答。
    Ping程序还能测出到这台主机的往返时间,大多数的TCP/IP实现都在内核中直接支持Ping服务,这种服务器不是一个用户进程。Ping程序通过在ICMP报文数据中存放请求的时间值来计算往返时间。当应答返回时,用当前时间减去存放在ICMP报文中的时间值,既是往返时间。

    2.2什么是传输包?

    将需要传输的数据分割为一个个小的单位进行传输的方法,就叫做包,如图:

     
    13566833-ef8b27002e508530.png
     

    通信过程中,每一个分组中都会附加上源主机地址和目标主机地址送给通信线路,这些发送端地址、接收端地址以及分组序号写入的部分就是“报文首部”;如果数据较大,分组过多,那么就有必要将分组序号写入包中,接收端会根据序号,分组按序重新装配为原始数据。(理解丢包就需要知道什么是包)

    2.3 什么是“三次握手,四次挥手”?

    TCP是一种面向连接的单播协议,在发送数据前,通信双方必须在彼此间建立一条连接。该“连接”就是客户端和服务器的内存里保存的关于ip地址、端口号等对方的信息。TCP可以看成是一种字节流,它会处理IP层或以下的层的丢包、重复以及错误问题。在连接的建立过程中,双方需要交换一些连接的参数。这些参数可以放在TCP头部。

    TCP提供了一种可靠、面向连接、字节流、传输层的服务,采用三次握手建立一个连接,采用4次挥手来关闭一个连接。

    2.4 为什么要“三次握手,四次挥手”?

    1)所谓三次握手(Three-way Handshake),是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。三次握手的目的是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号并交换 TCP 窗口大小信息。在socket编程中,客户端执行connect()时,将触发三次握手:即客户端和服务端通信前要进行连接,“3次握手”的作用就是双方都能明确自己和对方的收、发能力正常。

     
    13566833-92ea8e9461019511.png
     

    第一次握手:客户端发送网络包,服务端收到。服务端得出结论:客户端发送能力、服务端接收能力正常。

    第二次握手:服务端发包,客户端收到。客户端得出结论:服务端接收、发送能力正常,客户端接收、发送能力正常。

    第三次握手:客户端发包,服务端收到。服务端得出结论:客户端接收、发送能力正常,服务端发送、接收能力正常。
    所以第一、二次握手,只是为了验证彼此的接收发送能力是否正常。经历上面的三次握手过程,客户端和服务端都确认了自己的接收、发送能力是正常的,就可以正常通信了。

    2)所谓四次挥手(four-way handshake),就是指TCP的连接的拆除过程需要发送四个包,客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作。

     
    13566833-30d93f441990d4d2.jpg
     

    TCP连接是双向传输的对等的模式,就是说双方都可以同时向对方发送或接收数据。客户端或者服务端皆可以主动发送指令告诉对方,我要关闭连接了,比如:
    客户端:我要关闭连接了(客户端发起Close)
    服务端:好,你关吧(服务端收到关闭指令,回了一个ACK)【此时客户端不可以向服务端传输数据,但是服务端仍然可以向客户端传输数据】
    服务端:我传完所有数据啦(发送一个FIN段来关闭向客户端传输方向上的连接)
    客户端:哦,好的,知道(发送ACK确认关闭连接)

    注意:接收到FIN报文的一方只能回复一个ACK, 它是无法马上返回对方一个FIN报文段的,因为结束数据传输的“指令”是上层应用层给出的,它只负责“搬运”。

    参考https://www.cnblogs.com/haiyan123/p/7777924.html
    https://www.jianshu.com/p/8e4eb47421f5

    阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680

    结束语

    希望读到这的您能转发分享和关注一下我,以后还会分享阿里P7 Android知识点及解析,您的支持就是我最大的动力!!

     
    18452536-f9647b6e16a958ff.jpg
  • 相关阅读:
    hdu1161 欧拉路
    ZOJ 3204 Connect them(字典序输出)
    [POJ1936]All in All
    [POJ1035]Spell checker
    [POJ2485]Highways
    [洛谷P3697]开心派对小火车
    【AIM Tech Round 5 (Div. 1 + Div. 2) 】
    What are the differences between an LES-SGS model and a RANS based turbulence model?
    How to permanently set $PATH on Linux/Unix?
    tar解压命令
  • 原文地址:https://www.cnblogs.com/Android-Alvin/p/12102736.html
Copyright © 2011-2022 走看看