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每次回车时会将\n传过去,需要在debug的时候去除,如果写一个client的话也要注意这一点。
tomcat Http11NioProtocol如何解析http请求及如何解决TCP拆包粘包的更多相关文章
- springboot 1.3.5升级1.5.9后 默认使用tomcat 8.5版本 get请求报400 异常信息为 The valid characters are defined in RFC 7230 and RFC 3986
1.springboot 1.3.5升级1.5.9后 默认使用tomcat 8.5版本而之前用的是tomcat7 get请求报400 异常信息为 The valid characters are ...
- Tomcat 配置文件的解析
转载:https://www.cnblogs.com/sunshine-1/p/8990044.html https://www.cnblogs.com/kismetv/p/7228274.html ...
- Tomcat工作原理解析!
Tomcat简介 作者:杨晓(http://blog.sina.com.cn/u/1237288325) 一.Tomcat背景 自从JSP发布之后,推出了各式各样的JSP引擎.Apache Gro ...
- 源码深度解析SpringMvc请求运行机制(转)
源码深度解析SpringMvc请求运行机制 本文依赖的是springmvc4.0.5.RELEASE,通过源码深度解析了解springMvc的请求运行机制.通过源码我们可以知道从客户端发送一个URL请 ...
- TOMCAT原理详解及请求过程
Tomcat: Tomcat是一个JSP/Servlet容器.其作为Servlet容器,有三种工作模式:独立的Servlet容器.进程内的Servlet容器和进程外的Servlet容器. Tomcat ...
- 网站开发进阶(四)Tomcat Server处理一个http请求的过程
Tomcat Server处理一个http请求的过程 假设来自客户的请求为: http://localhost:8080/wsota/wsota_index.jsp 1) 请求被发送到本机端口8080 ...
- TOMCAT原理详解及请求过程(转载)
转自https://www.cnblogs.com/hggen/p/6264475.html TOMCAT原理详解及请求过程 Tomcat: Tomcat是一个JSP/Servlet容器.其作为Ser ...
- Tomcat Server处理一个http请求的过程
Tomcat Server处理一个http请求的过程 假设来自客户的请求为: http://localhost:8080/wsota/wsota_index.jsp 1) 请求被发送到本机端口8080 ...
- 在ASP.NET MVC 框架中调用 html文件及解析get请求中的参数值
在ASP.NET MVC 框架中调用 html文件: public ActionResult Index() { using (StreamReader sr = new StreamReader(P ...
随机推荐
- 蓝桥杯-PREV3-带分数
有人管蓝桥杯叫暴力杯,现在感觉还是挺贴切的.看到这题首先想到让i从1到n循环,首先判断i中无重复数字,再怎样判断能否用剩下的数构成n - i的假分数.之后看了题解.发现思路错了. 总结两点: 1.蓝桥 ...
- Linux下文件 ~/.bashrc 和 ~/.bash_profile 和 /etc/bashrc 和 /etc/profile 的区别 | 用户登录后加载配置文件的顺序
转自 https://blog.csdn.net/secondjanuary/article/details/9206151 文件说明: /ect/profile 此文件为系统的每个用户设置环境信息, ...
- 《hdu 4540 威威猫打地鼠》
威威猫系列故事——打地鼠 Time Limit: 300/100 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total ...
- 使用fiddler盖楼评论
使用fiddler盖楼评论:使用replay重复请求某接口
- 吴裕雄--天生自然 R语言开发学习:处理缺失数据的高级方法(续一)
#-----------------------------------# # R in Action (2nd ed): Chapter 18 # # Advanced methods for mi ...
- Luogu_2876_[USACO07JAN]解决问题Problem Solving
题目描述 过去的日子里,农夫John的牛没有任何题目. 可是现在他们有题目,有很多的题目. 精确地说,他们有\(P(1 \leq P \leq 300)\)道题目要做. 他们还离开了农场并且象普通人一 ...
- Java Random函数
Java中存在着两种Random函数: 1.java.lang.Math.Random: 调用这个Math.Random()函数能够返回带正号的double值,该值大于等于0.0且小于1.0,即取值范 ...
- e代驾推出新产品“e代喝”,能否实现前者的社交梦?
近日,关于e代驾推出e代喝的新闻不断出现在各大媒体的新闻报道之中,看似好像是替人排扰解难的征服酒局的又一利器.但事实真的如此吗?首先要弄清楚的,是目前e代驾在行业中的处境.作为代驾行业的先驱者,e代驾 ...
- UMD: 通用模块规范
既然CommonJs和AMD风格一样流行,似乎缺少一个统一的规范.所以人们产生了这样的需求,希望有支持两种风格的“通用”模式,于是通用模块规范(UMD)诞生了.
- mysql 分表实现方法详解
如果你需要进行mysql分表了我们就证明你数据库比较大了,就是把一张表分成N多个小表,分表后,单表的并发能力提高了,磁盘I/O性能也提高了.并发能力为什么提高了呢,因为查寻一次所花的时间变短了,如果出 ...