• tomcat Http11NioProtocol如何解析http请求及如何解决TCP拆包粘包


    前言

    tomcat是常用的Web 应用服务器,目前国内有很多文章讲解了tomcat架构,请求流程等,但是没有如何解析http请求及如何解决TCP粘包拆包,所以这篇文章的目的就是介绍这块内容,一下内容完全是个人查看tomcat nio 相关源码来总结的,源码版本9.0.30,欢迎提问,欢迎指出错误。

    请求解析

    参数在请求行时的请求形式

    GET /myServlet?name=zhangsan HTTP/1.1
    Connection: keep-alive

    参数在请求体时的请求形式

    POST /myServlet HTTP/1.1

    Connection: keep-alive

    name=zhangsan

    中间有一个空行表示请求头和请求体的分界。

    解析请求行

    以 GET /myServlet?name=zhangsan HTTP/1.1为例

    将请求行按空格进行分割,将method(POST),requestURI(/myServlet ),protocol(HTTP/1.1 )存起来

    将?之后的数据存入queryString(name=zhangsan)存起来。

    一直遇见换行符解析结束。

    解析请求头

    以这个为例

    Content-Length: 13

    Connection: keep-alive

     

    name=zhangsan

    解析过程很简单,以":"进行分割,一直到读取到一个只有换行符的空行,请求头解析结束。

    解析请求体

    请求体解析是通过请求头中的Content-Length来进行解析的,读取Content-Length值中对应的字节数。

    如何解决拆包粘包

    知道了请求结果和解析流程,下面就介绍一下怎样处理拆包粘包。

    粘包

    粘包的解决是非常简单的,比如粘包后是这样的数据。

    POST /myServlet?name=liuhao HTTP/1.1

    Content-Length: 13

     

    name=zhangsan

    POST /myServlet?name=liuhao HTTP/1.1

    tomcat处理请求时根据Content-Length进行读取,是不会读到第二个请求的,如果没有Content-Length的话也就没有请求体,请求头和下一个请求有空行,也不会读取。

    拆包

    拆包的处理方式大致相同就是数据没有读取完成就等

    请求行拆包

    POST /myServlet?name=liuh

    请求行拆包,请求行结束的标志是换行符,如果没有收到换行符,表示请求行没有解析完,这个时候会重新监听读事件(使用java nio selector),之前的数据会放到buffer中缓存。

    请求头拆包

    POST /myServlet?name=liuhao HTTP/1.1

    Content-Type:

    请求头拆包,请求头结束的标志是空行,如果没有只有换行符的空行,表示请求行没有解析完,这个时候会重新监听读事件(使用java nio selector),之前的数据会放到buffer中缓存。

    请求体拆包

    POST /myServlet HTTP/1.1

    Content-Length: 13

    Connection: keep-alive

     

    name=

    请求体拆包,请求体结束的标志是数据读取足够的字节数,如果读取不够,会阻塞的读取数据直到读取成功或超时报错。

    源码阅读指南

    将tomcat的源码导入到IDE,然后从架构和原理来了解tomcat,之后可以通过阅读其他博客来了解源码,最后自己在IDE中查看相关源码,如果看的吃力,可以debug来看,如果想看拆包解包的源码,可以用postman发送一个完整的http请求,然后使用telnet来进行拆包粘包测试,也可以写一个client来测试,不过有一点要注意,telnet每次回车时会将 传过去,需要在debug的时候去除,如果写一个client的话也要注意这一点。

  • 相关阅读:
    善用js 异步引入,大幅提升vue站点加载速度,媲美大厂流畅性
    react hooks useState 赋值优化解决方案
    vue hash模式下的微信授权详解
    图片之间没加空格有间隙的解决方案
    React 父组件重新渲染,子组件不需要渲染的三种性能优化方式(PureComponent,memo,shouldComponentUpdate);
    uniapp历史模式history配置
    vue下请求数据地址的封装
    h5 下ios适配底部小黑条,简单解决方案,只需一步
    overflow:hidden 失效问题
    h5下数字,字母不换行的解决方案
  • 原文地址:https://www.cnblogs.com/zhandouBlog/p/12507920.html
Copyright © 2020-2023  润新知