zoukankan      html  css  js  c++  java
  • 一次websocket的抓包体验

    一个简单的demo

    我们知道websocket一种服务端推送技术,首先Websocket是基于HTTP协议的,或者说借用了HTTP的协议来完成一部分握手。后续数据传递是基于TCP的。

    客户端代码

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>websocket client</title>
    </head>
    <body>
      <button id="open">open</button>
      <button id="send">send</button>
      <button id="close">close</button>
      <script type="text/javascript">
        (function (){
          let ws = null;
    
          document.querySelector("#open").addEventListener('click', e => {
            ws = new WebSocket("ws://127.0.0.1:8080");
    
            ws.addEventListener('open', e => console.log('open event, %o', e));
            ws.addEventListener('message', e => console.log('message event, %o', e));
            ws.addEventListener('close', e => console.log('close event, %o', e));
            ws.addEventListener('error', e => console.log('error event, %o', e));
          });
    
          document.querySelector("#send").addEventListener('click', e => {
            ws.send('hello');
          });
    
          document.querySelector("#close").addEventListener('click', e => {
            ws.close();
            ws = null;
          });
        })()
      </script>
    </body>
    </html>
    

    服务端代码

    const WebSocket = require('ws');
    
    const wss = new WebSocket.Server({ port: 8080 });
    
    wss.on('connection', function connection(ws) {
      ws.on('message', function incoming(message) {
        console.log('received: %s', message);
        ws.send('hello too!');
      });
    
      ws.send('something');
    });
    

    输出结果

    open event, Event
    message event, MessageEvent
    message event, MessageEvent
    close event, CloseEvent
    

    细节

    求头信息

    从浏览器中可以看到ws握手的请求头信息

    GET ws://127.0.0.1:8080/ HTTP/1.1
    Host: 127.0.0.1:8080
    Connection: Upgrade
    Pragma: no-cache
    Cache-Control: no-cache
    Upgrade: websocket
    Origin: http://zj.h5.m.taobao.com
    Sec-WebSocket-Version: 13
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.8
    Cookie: OUTFOX_SEARCH_USER_ID_NCOO=1973383732.1783078; l=AujoRgw9fUEEs1APUgk9dNwgONz6EUwb
    Sec-WebSocket-Key: 7iAt/aVzQLvkwZmO6eHr3A==
    Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
    

    解释:

    Upgrade: websocket
    Connection: Upgrade
    

    表示发起的是Websocket协议。

    返回头信息

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: 32BWzg94jPj8C0kXzqHAru5pGbw=
    

    101 code 转换协议:101 Switching Protocols
    服务器已经理解了客户端的请求,并将通过Upgrade 消息头通知客户端采用不同的协议来完成这个请求。在发送完这个响应最后的空行后,服务器将会切换到在Upgrade 消息头中定义的那些协议。
    只有在切换新的协议更有好处的时候才应该采取类似措施。例如,切换到新的HTTP 版本比旧版本更有优势,或者切换到一个实时且同步的协议以传送利用此类特性的资源。

    之上是应用层协议的内容,用wireshark抓包看下底层细节,先梳理下TCP协议本身。

    wireshark

    websocket握手

    这是握手时HTTP协议底层依赖的TCP三次握手机制:最后一个是告诉客户端没有内容发送了。8080 为服务端端口号,61476 端口为客户端端口号。

    websocket 握手成功

    HTTP 101 协议转换

    从HTTP 协议转为 websocket 协议,5001 端口号为 websocket 服务的端口号。

    websocket 的一个数据包

    关闭 websocket

    可以看出61475端口一开始为HTTP服务的,后来由于101返回码,61475 端口转为 websocket 的 5001 端口号,服务端的8080端口对接客户端的5001端口号。关闭websocket时,由 61475 端口号发起关闭 5001 请求,与此同时 61475 端口和 服务端的8080端口通信,告诉服务端我要关闭端口,成功后61475 再告诉 5001 端口,我关闭成功了。整个关闭流程结束。

  • 相关阅读:
    Linux(CentOS 7)命令行模式安装VMware Tools 详解
    最全面的移动APP测试点
    利用Fiddler编写Jmeter接口测试
    LeetCode | TwoSum
    Python
    Django
    浅谈web网站架构演变过程
    Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解
    Web服务器之Nginx详解(操作部分)
    Web服务器之Nginx详解(理论部分)
  • 原文地址:https://www.cnblogs.com/xiaoniuzai/p/7588739.html
Copyright © 2011-2022 走看看