个把月前,阿拉在某处看到有人对大神的描述——公司内部加外援搞了几天没解决的网络问题,只见那人抓了数据包,分析出数据首部信息有误,然后用了某工具将1改成了0,遂网络恢复。

阿拉以为那是很神奇的技能。直到今天了悟,神奇的技能是人人皆能习得的。

啊呀,甚至不能说是神奇。只是算是职业素养的范畴。i_f29.gif大概是厉害的师傅领阿拉入的门,阿拉觉得自己将会无所不能呢。

虽然讲知识的前辈多的是,阿拉就以平级的理解来说点接地气的东西吧。但愿你也能在平辈的论述中理解晦涩的言论,然后逐渐的,形成适合自己的知识探究体系。

之前阿拉写过浅谈主机间网络通信实际过程。现在看来是有诸多诟病的。知识是递进的,不是模块化的,我们总在推翻自己之前的观点,那啥,对,推陈出新,也就这么回事。啊啊,其实主要是不够完善,想来是那时候还太悠哉了,写东西也慢的不行,效率捉急0.0。

为了尽量全面,阿拉所言并不深入,甚至每个小部分深究都是大学问。这里就以宽度为主了,深度交给你。

好,来看。



PART1.Internet网络通信

套接字地址

在建立通信连接的每一端,进程间的传输要有两个标志:

IP地址和端口号,合称为套接字地址 socket address 

客户机套接字地址定义了一个唯一的客户进程

服务器套接字地址定义了一个唯一的服务器进程

IP地址确定主机,端口号确定应用程序。就像收快递有了地址的大范畴还要有手机号姓名落实到个人。

默认端口常常忽略不写。http的默认端口为80,若端口号为8080时,就要写成诸如192.168.0.10:80的形式了。


socket套接字

进程间通信IPC的一种实现,允许不同主机或同一主机上不同进程之间通信和数据交换。

Socket API(应用程序接口):封装了内核中所提供的socket通信相关的系统调用(应用程序位于用户空间,经kernel调用内存信息,然后将处理后的信息由kernel传达至应用,这一过程要使用套接字。

Socket Domain:根据所使用的地址分为

    AF_INET:Address Family,IPv4

    AF_INET6:IPv6

    AF_UNIX:同一主机上不同进程之间通信时使用(为了方便数据传输。同一主机不同进程还要跨网络的话太麻烦啦!)

Socket Type:根据使用的传输层协议

    SOCK_STREAM:流,tcp套接字,可靠传输,面向连接

    SOCK_DGRAM:数据报,udp套接字,不可靠传输,无连接

    SOCK_RAW:裸套接字,无须tcp或udp,app直接通过IP包通信(即同一主机不同进程通信使用)

wKioL1nkpbPjGZauAADMpSbVsVA080.png

socket套接字函数:

wKioL1nkpbOQvke-AAFqrv8mvnc012.png

套接字相关的系统调用:socket():创建一个套接字;bind():绑定IP和端口;listen():监听;accept():接收请求;connect():请求连接;write():发送;read():接收;close():关闭连接。


http服务通信过程

wKioL1nkqDKw0hiEAAH2jR0ISNE613.png


此外,发送端每经过一层增加http报文首部信息。应用层仅有http数据,经传输层增加TCP首部,经网络层增加IP首部信息,经数据链路层增加以太网首部。接收端每通过一层则删除掉其层次对用的首部信息,直至应用层得到完整的http数据。

httpHyper Text Transfer Protocol,超文本传输协议。默认使用tcp的80端口。

语言:http所用语言为html语言。html:Hyper Text Markup Language,即超文本标记语言。此外还有css和js等语言。

MIME:Multipurpose Internet Mail Extensions,即多用途互联网邮件扩展。最初的http仅有邮件服务一项功能,后来http能够传输的文件格式增多,统一称为MIME。(即http页面支持添加的文件格式,如MP3,jpg等,每个文件称为一资源)centos中/etc/mime.types有详细的MIME可传输文件格式说明。详细说明见:http://www.w3school.com.cn/media/media_mimeref.asp

http协议:

http/0.9:1991年,仅有GET一个命令。

http/1.0:1996年,支持cache,MIME,method(http获取请求的方法)。不支持持久连接,每次请求仅能接受一个资源(即文件)。引入了POST和HEAD命令。头信息是ASSII码,后面数据可以为任何格式。服务器回应时会告诉客户端,数据是什么格式,即Content-type字段的作用。这些数据即是MIME。每个值包括一级特征和二级特征,预定义的类型,也可以自定义类型。

常见的Content-Type值:text/xml p_w_picpath/jpeg audio/mp3

http/1.1:1997年,引入了持久连接(persistent connection),即一次连接可处理多个请求。引入了管道机制(pipelining),即一个TCP连接里,客户端可以同时发送多个请求,此机制提高了http协议的效率。新增方法:PUT,PATCH,OPTIONS,DELETE(下面会详细介绍)。但在同一个TCP连接里,所有的数据通信时按次序进行的。服务器只能按顺序处理回应,前面的回应慢,会有很多请求排队,造成“队头堵塞”(head-of-line blocking)。为避免此问题,有两种方法:一是减少请求数,二是同时多开持久连接。网页优化技巧,比如合并脚本和样式表,将图片嵌入css代码,域名分片(domain sharding)等。http协议不带有状态,每次请求都必须附上所有信息。请求的很多字段都是重复的,浪费带宽,影响性能。

http/2.0:2009年谷歌研发,2015年被定为国际标准。头信息和数据体都是二进制,安全性大大提高。复用TCP连接,同一连接里,客户端和浏览器都可以同时发送多个请求和回应,且不用按顺序,避免“队头堵塞”,此双向的实时通信成为多工(Multiplexing)。引入头信息压缩机制(header compression),头信息使用gzip或compress压缩后再发送;客户端和服务器同时维护一张头信息表,所有字段都会存入此表,生成一个索引号,只发送索引号,提高速度。http2.0允许服务器未经请求,主动向客户端发送资源,即服务器推送(server push)

至今http1.1还是主流,http2.0为什么没能普遍应用?一方面是技术,另一方面的原因————哈哈,大概就是centos8都快出了,centos6还是主流一样。

工作机制:

http请求:http request

http响应:http response

一次http事务:请求<-->响应

Web资源:web resource 。一个网页由多个资源构成,打开一个页面,会有多个资源展示出来,但是每个资源都要单独请求。因此,一个“Web 页面”通常并不是单个资源,而是一组资源的集合。

静态文件:无需服务端做出额外处理

    文件后缀:.jpg, .html, .txt, .js, .css, .mp3, .avi

动态文件:服务端执行程序,返回执行的结果

    文件后缀:.asp, .php, .jsp

提高HTTP连接性能

并行连接:通过多条TCP连接发起并发的http请求

持久连接:keep-alive,长连接,重用TCP连接,以消除连接和关闭的时延,以事务个数和时间来决定是否关闭连接

管道化连接:通过共享TCP连接发起并发的http请求

复用的连接:交替传送请求和响应报文(实验阶段)

串行、持久连接和管道:

wKioL1nlVhLT1WtXAAIUpowMrCo025.png



URL

URI:Uniform Resource Identifier统一资源标识,分为URL和URN

    URN:Uniform Resource Naming,统一资源命名

        如P2P下载使用的磁力链接,即迅雷种子型的

    UPL:Uniform Resource locator,统一资源定位符

        如浏览器地址栏的网址

    两者区别:URN为名称,URL为地址,URN定义身份,URL提供查找方式。URN仅用于命名,而不指定地址。

URL组成

<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>

schame:方案,访问服务器以获取资源时要使用哪种协议

user:用户,某些方案访问资源时需要的用户名

password:密码,用户对应的密码,中间用:分隔

Host:主机,资源宿主服务器的主机名或IP地址

port:端口,资源宿主服务器正在监听的端口号,很多方案有默认端口号

path:路径,服务器资源的本地名,由一个/将其与前面的URL组件分隔

params:参数,指定输入的参数,参数为名/值对,多个参数,用;分隔

query:查询,传递参数给程序,如数据库,用?分隔,多个查询用&分隔

frag:片段,一小片或一部分资源的名字,此组件在客户端使用,用#分隔

如:

http://www.ardusty.com

http://www.magedu.com:8080/p_w_picpaths/logo.jpg

ftp://mage:password@172.16.0.1/pub/linux.ppt

rtsp://videoserver/video_demo/

http://www.magedu.com/bbs/hello;gender=f/send;type=title

https://list.jd.com/list.html?cat=670,671,672&ev=149_2992&sort=sort_totalsales15_desc&trans=1

http://apache.org/index.html#projects-list


网站访问量

IP:Internet protocol(IP数,不更换IP不重新计数)

PV:Page View(刷新次数,点击量)

UV:Unique Vistor(一天内访问的主机数,cookie实现)


PART2.一次完整http请求处理过程

web请求处理步骤:

wKioL1nldonQLBciAAImBiH029E447.png


一次完整的http请求处理过程

1.建立连接:接收或拒绝连接请求

2.接收请求:接收客户端请求报文中对某资源的一次请求的过程

web访问响应模型(wed I/O)

    单进程I/O模型:启动一个进程处理用户请求,而且一次只处理一个,多个请求被串行响应

    多进程I/O模型:并行启动多个进程,每个进程响应一个连接请求

    复用I/O模型:启动一个进程,同时响应N个连接请求

实现方法:多线程模型和事件驱动

    多线程模型:一个进程生成N个线程,每线程响应一个连接请求

    事件驱动:一个进程处理N个请求

    复用的多进程I/O模型:启动M个进程,每个进程响应N个连接请求,同时接收M*N个请求

3.处理请求:服务器对请求报文进行解析,并获取请求的资源及请求方法等相关信息,根据方法,资源,首部和可选的主体部分对请求进行处理

元数据:请求报文首部

        <method> <URL> <VERSION>

        HEADERS 格式 name:value

        <request body>

示例:

    host:www.ardusty.com 请求的主机名称

    Server:Apache/2.4.7

HTTP常用请求方式,Method

    GET,POST,HEAD,PUT,DELIETE,TRACE,OPTIONS

4.访问资源

服务器获取请求报文中请求的资源web服务器,即存放了web资源的服务器,负责向请求者提供对方请求的静态资源,或动态运行后生成的资源

资源放置于本地文件系统特定的路径:DocRoot

        DocRoot-->/var/www/html

        /var/www/html/p_w_picpaths/logo.jpg

        http://www.ardusty.com/p_w_picpaths/logo.jpg

web服务器资源路径映射方式

    a.docroot

    b.alias

    c.虚拟主机docroot

    d.用户家目录docroot

5.构建响应报文

一旦web服务器识别出了资源,就执行请求方法中描述的动作,并返回响应报文。响应报文中包含有相应状态码,响应首部,如果生成了响应主体的话,还包括响应主体。

1)响应实体:如果事务处理产生了响应主体,就将内容放在响应报文中回送过去。响应报文中通常包括:

    描述了响应主体MIME类型的Content-Type首部

    描述了响应主体长度的Content-Length

    实际报文的主体内容

2)URL重定向:web服务构建的响应并非客户端请求的资源,而是资源另外一个访问路径。

    如http://www.360buy.com地址栏跳转会跳到www.jd.com

3)MIME类型:web服务器要负责确定响应主体的MIME类型。多种配置服务器的方法可将MIME类型与资源管理起来。

    魔法分类:Apache web服务器可以扫描每个资源的内容,并将其与一个已知模式表(被称为魔法文件)进行匹配,以决定每个文件的MIME类型。这样做慢,但方便,尤其文件没有标准扩展名时

    显示分类:可以对web服务器进行配置,使其不考虑文件的扩展名或内容,强制特定文件或目录内容拥有某个MIME类型(提高性能但可文件获取受制于后缀名)

    类型协商:有些web服务器经过配置,可以以多种文档格式来存储资源。在这种情况下,可以配置web服务器,使其可以通过与用户协商来决定最好使用哪种格式(及其相关的MIME类型)

6.发送响应报文

web服务器通过连接发送数据时也会面临与接收数据一样的问题。服务器可能有很多条到各个客户端的连接,有些是空闲的,有些在向服务器发送数据,还有一些在想客户端发送响应数据。服务器要记录连接的状态,还要特别注意对持久连接的处理。对非持久连接而言,服务器应该在发送了整条报文之后,关闭自己这一端的连接。对持久连接来说,连接可能仍保持打开状态,在这种情况下,服务器要正确计算Content-length首部,不然客户端就无法知道响应什么时候结束了。

7.记录日志

当事务结束时,web服务器会在日志文件中添加一个条目,来描述已执行的事务。