zoukankan      html  css  js  c++  java
  • 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的话也要注意这一点。

  • 相关阅读:
    Java字符集
    ==和equals区别
    web.xml中load-on-startup标签的含义
    使用solrJ管理索引——(十四)
    Solr管理索引库——(十三)
    [置顶] 关于redhat系统yum源的配置1
    设置Oracle用IP远程连接和客户端访问
    jqueryUI中datepicker的使用,解决与asp.net中的UpdatePanel联合使用时的失效问题
    [置顶] 关于redhat系统yum源的配置2
    浅析innodb_support_xa与innodb_flush_log_at_trx_commit
  • 原文地址:https://www.cnblogs.com/zhandouBlog/p/12507920.html
Copyright © 2011-2022 走看看