目录
一、说明
1. Smsniff 整个讲解过程中,主要用到Smsniff这个软件(网络数据包拦截软件[抓包工具]),用于监测、查看电脑与外界网络的通信数据包。
二、HTTP基础知识
1. HTTP协议的请求响应过程(通常情况通过一次TCP连接完成)
- 例子:比如,浏览器访问湖南理工学院的教学一体化服务平台:http://bkjw.hnist.cn/jsxsd/index.jsp
拦截到的数据:我们看看这个请求过程中拦截到了什么数据。
- 这里可以看出的确是通过TCP Protocol(TCP协议)传输的数据。这里一条记录代表一次TCP连接。
首先是一个GET请求
GET /jsxsd/index.jsp HTTP/1.1 Host: bkjw.hnist.cn Connection: keep-alive Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9
对我们而言唯一有意义的就是
GET /jsxsd/index.jsp HTTP/1.1
Host: bkjw.hnist.cn
对比我们的网址链接http://bkjw.hnist.cn/jsxsd/index.jsp聪明的你你应该懂了然后看看客户端返回给我们的数据。
HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Set-Cookie: JSESSIONID=1D0E1BA32DD11F8F4EFB8804EB7140FE; Path=/ Content-Type: text/html;charset=GBK Transfer-Encoding: chunked Content-Encoding: gzip Vary: Accept-Encoding Date: Mon, 14 May 2018 05:44:01 GMT a .......... 200 .X.o............ ..%K.%.@.xX.$..g..e..w.iS$K.-....t.:t_..Y.'m....ds~5M.eE....".....a...#)J..4s`....}...=w........c?YZ...ed...N.}...%..1.Yy .c+...?^9y..."Z .....\.`.|JC..._.....z...t..k./l...?.y.Y..j..Zz.w.7lN.c...+.Z....]. ......^ojK.....+.>......g}....L..!.....s..........~z....~s../...m....}t....o^......_.\.v...V...B3.}.8..]..u.F5..fS..a?....K... ......".;..`n.@...:..u.....N..9.....[.n.t..[..U.....Lo{AWo.....n.~.uA....-.3...<.tn....P. ........%A.v.ED".5P...o...l...w>x...o.......[..j.s..x.K.Q.L.....e"2lwI 200 ...v).c..B.n.4........U.... ....M.U..T.5..51...a.....k..\..kS..tmi^x.AT[..K.........Qs.....0.p{...K...*.%.J..b.NZ..D.5.9[...h].RF.=.u...Y.4....xA.P.\.`G..... .....x..E.....rl...b....Q{.O.b.l.F...w2.a...?...^Z^@YP7.>..6E.... .d}k..........>..9.m.T..a.S3$....T...0j..x2G..x.........9.hO.Q;...Q..7..t........T./.Mj...1..h.K'...W.6'...L.+.s....h.)%*.g.*......d.5;!...@BF...^@$-.s.. ..X..pr ...B..1. U...>....x..i..+..M
这个后面还有一堆看不懂的乱码,这些看似乱码的数据,其实就是是压缩过后的网页内容。(压缩是为了减少流量,提高速度等等)
- 分析:这样是一个http协议中最传统的过程。这反应了以下几个特点。
- http协议中,服务器永远是被动的接受请求,客户端才能主动。
- 一次请求完成,接收到响应后,就断开TCP连接。(当然,有时不一定是只有一个请求发出,比如有时候会响应Location重定向,这时候就可能会有多个请求发出,在一次tcp过程中)
三、Ajax的理解
- 引用百度百科:Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML)
- Ajax是由JavaScript实现的,首先我们需要知道关于JavaScript三点
- 浏览器能够运行JavaScript代码。
- 浏览器上运行的JavaScript可以操作网页上的内容(如果没用过也没事,就知道有这一特点就好,后面会用到)。
- 浏览器上的JavaScript可以发送http请求,例如GET,POST等等。(使用浏览器提供的XMLHttprequest类实现。这不是本文重点)
- 有上面这三点,就能够实现Ajax,其实Ajax离我们并不远,比如
- 网页并没有整体刷新,而只是下面的搜索结果部分,随着搜索框内容改变而变更显示的结果。
那这样的效果,当然是Ajax,那具体的工作流程又是怎么样的呢?
抓包测试,究竟是不是跟我说的一样,JavaScript发送http请求去获取数据呢。我之前写过的一个Ajax实现的类似百度搜索,一样的搜索学生的。我们来看看是不是有HTTP请求,请求的内容是不是输入的内容呢。
- 下面是演示效果动画
数据包
发送的数据
GET /GPMS/public/createProject/getStudentInfoByName?search=%E9%AA%9A HTTP/1.1
Host: 120.79.53.18
Connection: keep-alive
Accept: application/json, text/javascript, /; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
Referer: http://120.79.53.18/GPMS/public/createProject/projectChecklist
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie:XSRF-TOKEN=eyJpdiI6IjZrMWRKdmtcL2huakhpYWxNUHFZR1RBPT0iLCJ2YWx1ZSI6Ik1rcUpNQU9YYXozMXg2UkdNQ3dpSE1UR0RicGN4ek5iMXRyZnM3NVJCVjZEdzZhakt3aGRKZ0R4SHFoU0xxcXc2SEJYaFJYZUpBMFBOdkZ3SXByeHJBPT0iLCJtYWM- 这是个GET请求,那么参数会在URL中,也就是上面绿色的部分,由于,中文在传输时会进行URL编码。我们需要解码一下。(为什么要对中文进行URL编码,可以暂时不用理解,想理解自行百度)
- 这就说明的确是发出了请求,并携带了输入框的内容。
- 这是个GET请求,那么参数会在URL中,也就是上面绿色的部分,由于,中文在传输时会进行URL编码。我们需要解码一下。(为什么要对中文进行URL编码,可以暂时不用理解,想理解自行百度)
接收到的数据
HTTP/1.1 200 OK
Date: Mon, 14 May 2018 09:36:38 GMT
Server: Apache/2.4.27 (Win64) OpenSSL/1.0.2k PHP/7.1.9
X-Powered-By: PHP/7.1.9
Cache-Control: no-cache
Set-Cookie: XSRF-TOKEN=eyJpdiI6ImpSZ0dEb256SEtZU0dzV2xib0QrMGc9PSIsInZhbHVlIjoiUW1ETmJGMDlrY1VuTUU4c0lnQjVsc3JNQm1aYlpkR1ZmcjFadGNESGgwNjBxQzNBbG0rNlYzeXc1eXZvN0QxM2pIcDBBa2txbkkyaXp4OUowVUg5clE9PSIsIm1hYyI6IjM3YmIwM2RkZjY2YmQ5OGQwYWQzYmJlMjU1MzAxNzlhMzA3YTJhZWQ1MjVmZjExNzM1ZjdlOTQ3ZDA5MDg2ZjIifQ%3D%3D; expires=Mon, 14-May-2018 11:36:38 GMT; Max-Age=7200; path=/
Set-Cookie: laravel_session=eyJpdiI6ImN6SURrVEMxbGI5SzErM0E3dVVoWGc9PSIsInZhbHVlIjoiSDFRNTd2V0pIUlwvQWJLcVNnMHN0bWQ3emp5ZjhmWitPblwvXC8xek9xN28xVmdqeEhlUlB1OGFJTWVjMzZSNmU1Ynl0YmZ5bXlGSGhGQyswNkxueFpxdVE9PSIsIm1hYyI6IjFiZDY1MjIwN2FkNGU3ODA4Y2I1MTlkNGYyYzQwOWZjNGU1ZDhkMDgzYzBkZWM1NDMyZGQxYzdiMjFlZGQ5NmUifQ%3D%3D; expires=Mon, 14-May-2018 11:36:38 GMT; Max-Age=7200; path=/; HttpOnly
Content-Length: 131
Keep-Alive: timeout=5, max=98
Connection: Keep-Alive
Content-Type: textml; charset=UTF-8
{“results”:[{“id”:”14162400892”,”text”:”\u9a9a\u5b66\u751f(14162400892)”},{“id”:”14162400894”,”text”:”\u9a9a\u732a(14162400894)”}]}- 最后一行的数据(Body里面),从results这个单词就能看出,这是搜索的结果,里面还有我们的学号在里面,肯定没错。这里中文又进行了编码,不过这次是Unicode编码了,继续解码 在线解网站
- 返回的数据没错吧,这样的数据是Json对象,为了方便处理,通常返回的数据都是Json数据。
- 最后一行的数据(Body里面),从results这个单词就能看出,这是搜索的结果,里面还有我们的学号在里面,肯定没错。这里中文又进行了编码,不过这次是Unicode编码了,继续解码 在线解网站
- 结论:的确是JS发送HTTP请求到服务器,然后把返回的数据展示到页面上的。
- Ajax的优点:能够在不重新获取整个网页的情况下,更新网页的部分的内容。减少流量,并且给用户提供更好的体验,例如百度这种,输入提示。
- 下面是演示效果动画
四、cookie和session的理解
必须要知道的几点
- cookie和session功能就是存储数据。cookie存储形式更单一 : 以键值对(key:value)的形式存储。session则没有固定的结构(可以文件实现,数据库实现,等等)。通常也可以是键值对。
- cookie和session两者存在的位置不同,cookie是在浏览器内的。而session存在于服务器上。
- 在你访问百度时,浏览器会把属于www.baidu.com这个网站的cookie,放在http数据包中带给服务器。
- cookie和session都有有效时间,每次的使用会加满有效时间,长期不使用就过期咯。
cookie和session常用于把http协议变得“有状态”
- HTTP协议无状态的意思,例如,A用户访问网页,向服务器发送请求A。B用户访问网页,向服务器发送请求B。服务器并不能知道A请求和B请求分别是谁发出来的。(服务员也是这样,一天服务那么多人,服务完之后,哪还记得你是谁)
怎么让服务器认识你呢?有下列的方式。
- cookie不是会带给服务器么。那我把我的支付宝账号和密码存储在Cookie里面,然后带给服务器,服务器不就认识我了么?是的,是会认识你。这样黑客也会想认识你,cookie本身是不安全的。所以,账号密码存储在cookie中显然不是明智的做法,黑客很容易从你的浏览器中盗取到你的cookie。
- 账号密码存在cookie不安全,那我登陆的时候把账号密码发给服务器,然后,服务器把账号密码存到session的一个房间里,然后把唯一的房间号码发回给我,我把这个房间号(房间号也就是常说的session_id或者session_key)放在cookie中。是不是服务器能通过这个房间号找到我的账号和密码呢?是的,这样做到了账号密码没有存储在浏览器上,做到了信息存储安全。那黑客要是也拿着我的房间号找服务器怎么办呢。
- cookie的过期时间,能在一定程度上提高安全度。因为,解密也是需要时间的。当然也可能还不够安全。(至少长期看来是这样)
- 当然有更安全的方式 : csrf-token。这个不是本文重点,想了解自行百度。(没有绝对的安全)
当然cookie和session也可以用来存储其他的数据,不仅仅是账号密码(滑稽)。
五、webSocket的理解
首先要知道的几点
- socket是一个程序员应该理解的知识的。socket百度百科的定义:网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。Socket的英文原义是“孔”或“插座”。作为BSD UNIX的进程通信机制,取后一种意思。通常也称作”套接字“。
- 如果你没进行过socket编程,没了解过。那你应该知道以下两点。
- socket支持多种网络协议,如最常用的TCP(浏览器中,HTTP协议的数据包就是通过浏览器和服务器间的TCP连接传输的)、UDP(看视频时)。
- TCP连接建立需要一个握手的过程。(对于本文你只需要知道,这个握手过程需要消耗一定的时间就可以了)
问题来了,怎么实现网页实时通知(如有新邮件)
- 效果:我自己用手机给我邮箱发了条短信。(我并没有自己点刷新网页哦!我发誓,我的手在这 [曾广的左手和右手] )
要实现这样的效果,有什么困难呢。
实现的途径(虽然有困难但是还是可以实现的)
Ajax实现
- 看懂了上面Ajax的同学,一定能想到,Ajax不就可以向服务器发出请求吗,我们写一个js脚本。每隔一段时间就问服务器,有新邮件?有就把数据传给浏览器。
- js脚本问服务器:请问有我的邮件么?
服务器:没有…
js脚本问服务器:请问有我的邮件么?
服务器:还是没有……
js脚本问服务器:请问有我的邮件么?
服务器:我喉咙都哑了。没有………
js脚本问服务器:请问有我的邮件么?
服务器:有一封… (于是浏览器获取到了新邮件。然后。js脚本又继续在问了) - 缺点:这样的查询实现方式,实时性取决于js脚本,请求服务器的间隔时间。时间越短实时性越高。但是。可累死服务器了,毕竟那么多QQ邮箱用户。服务器可不是只为你服务的。
Long Polling 长轮询实现
- Long Polling是什么(这个概念我也是今天去了解webSocket的时候才看到的。)这个概念并不难理解,可以这样理解。
- 过程:
- 浏览器通过TCP连接发送给服务器一个请求。查询是否有新邮件的请求。
- 服务器收到这个请求后,没有新邮件就不应答。因为没应答,所以这次HTTP请求并没有完成。那TCP连接也不会中断。
- 当有新邮件时,服务器将数据通过刚刚那个TCP连接发回给浏览器。并关闭TCP连接。
- 浏览器接收到数据后,显示到页面上。于是又发起了下一次请求(也就是下一次Long Polling)。
- 意外:
- 浏览器设定了超时时间,如果超过这个时间没有返回,就会结束一次的Long Poling。
- 浏览器收到异常或者网络异常,就会中断。
- 优点:
- 解决了Ajax实现需要频繁请求服务器的问题。(减少了服务器的负担)
- 实时性也得到了一定的保障。
- 缺点:
- 虽然解决了Ajax一些缺点,但是每一次得到新的数据之后,还是需要重新发起一次请求。也就是一个新数据就要一次新请求。
- 效果:我自己用手机给我邮箱发了条短信。(我并没有自己点刷新网页哦!我发誓,我的手在这 [曾广的左手和右手] )
救世主(webSocket)“发展了这么久,还是回到了Socket、TCP”
- 什么是webSocket,既然名字里面都有Socket,肯定和Socket有很多相似处。webSocket的整体非常像TCP协议。
webSocket的握手
- 本文(跳转到目标处)中提到TCP连接建立过程中,需要握手,并且说到这个握手需要消耗时间。webSocket也是如此,它也需要握手的过程。
- 握手的过程,我们通过抓取浏览器与这个webSocket在线测试网站的webSocket服务器通信数据,进行研究。
webSocket实例
- 建立webSocket连接
- 向服务器发送了”sao”
- 实例演示
发送给服务器的数据
GET / HTTP/1.1
Host: 118.25.40.163:8088
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: http://www.blue-zero.com
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Sec-WebSocket-Key: LfjywyNGE81EHIQXiq/whA==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits- Connection: Upgrade、Upgrade: websocket这两个的意思很容易理解。连接:升级,升级:websocket。我们可以这样理解,就是告诉服务器,我要把协议连接升级到websocket。
- Sec-WebSocket-Version: 13 说明了浏览器webSocket协议的版本。
- Sec-WebSocket-Extensions: permessage-deflate; client_max_windo_bits 这个意思是要使用的websocket**扩展**有哪些的意思。
- Sec-WebSocket-Key: LfjywyNGE81EHIQXiq/whA==抓了几次,这个Key应试是浏览器随机生成的,网上查了一下,的确如此。
客户端接收的数据包
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: OqQk/5FMZW8c8RRpE+Vj73dy/9s=
.~..<b>..............................</b> <span style='font-size:20px;'>............<a style='font-weight:900;font-size:16px;' href='http://www.blue-zero.com/chat/' target='_blank'>...............[......]</a>.........websocket................................................</span>.j<b style='color:#ff9900;'>......(......)</b>...halo~...websocket..........................................
1. <font color=#228B22>绿色</font>部分Switching Protocols切换协议,<font color=#0000CD>蓝色</font>部分我就不说了,协议嘛都是固定的。 2. <font color=#FFA500>橙色</font>部分**Sec-WebSocket-Accept:** OqQk/5FMZW8c8RRpE+Vj73dy/9s= 看形式就是经过**base64**加密的,但是我试了解密,出来的却是乱码。于是百度查了一下。 3. 这个**Sec-WebSocket-Accept**是由从浏览器发送的**Sec-WebSocket-Key**拼接上”**258EAFA5-E914-47DA-95CA-C5AB0DC85B11**″这个被称之为”***魔术串***“的字符串。然后进行**sha-1**加密,将**sha-1**加密的**20位二进制的结果**又进行**base64**加密而得到的字符串。(难怪解密出来是乱码。二进制。不乱才怪) 4. Sec-WebSocket-Key获得Sec-WebSocket-Accept用**php**实现代码就是。
$key = “LfjywyNGE81EHIQXiq/whA==”;
$accept = base64_encode(sha1($key . ‘258EAFA5-E914-47DA-95CA-C5AB0DC85B11’, true));点击发送“sao”后的数据包
00000000 81 83 88 BA 1B 73 FB DB 74 …..s.. t
..<b>....................................</b>sao
- 上面的十六进制的内容应该就是sao(应该是进行了压缩),因为下面的服务器发给浏览器的内容里面就是sao。
webSocket建立和通信过程:
- (符合HTTP协议格式的数据)发送请求协议升级包,并携带Sec-WebSocket-Key
- (符合HTTP协议的数据)服务器使用Sec-WebSocket-Key生成Sec-WebSocket-Accept,并返回给用户。完成协议升级。
- 完成上面的握手步骤,之后,就可以像TCP协议一样,服务器可以向客户端发数据,客户端可以向服务端发数据啦。这就是为什么开头就说:“发展了这么久,还是回到了Socket、TCP”。只要网络不出问题,或者客户端不主动关闭TCP连接,这个连接是会一直保持的。
优点:
- 建立TCP连接只需要一次(减少了TCP连接握手上消耗的时间)。
- 建立TCP连接后,HTTP解析程序,只需要解析一次来自webSocket的握手包。(减少了HTTP解析的资源消耗)
- 是真正的有状态协议。(减少了以往HTTP请求中携带session_id或session_key,然后服务器要通过session_id**检索用户信息的消耗**)。
- 缺点:并不是所有的*都支持webSocket。
- 总结:其优点的三个减少(性能优化)。就能满足web应用,在一些需要服务器推送通知给客户端等等的场景的要求。
皮一下:当时理解了webSocket我就感慨。说白了webSocekt,就是tcp建立之后,加了个http形式的握手么。
过程就像,左手握了之后,用左手感觉了一会,没错这是个人的手(tcp连接建立),于是握上了右手,右手感觉到,没错这个手是我女朋友的右手(识别用户)。然后就,随便搞了。可以不用再握手,。识别是不是女朋友了。。左右手牵好就可以了。。。
(当然,女朋友是不存在的)
本文,由原来的XHTML在线编辑器。改为了使用Markdown编辑器。观看效果更优。
想问我问题扫下面的二维码,当然也可以留言
也可以支持我