Tomcat响应数据过程
创始人
2024-09-24 19:33:03
0

        我们在用Tomcat响应数据给客户端的时候,一般会调用如下代码

OutputStreamoutputStream=resp.getOutputStream(); outputStream.write("test".getBytes());

        Tomcat在响应客户端或者接受客户端消息的时候会用到门面模式,所以响应的时候Response的类型其实是ResponseFacade(接收的时候是RequestFacade),得到的socket.getOutputStream()得到的类型是CoyoteOutputStream类型(接受端也是,Coyote是核心类)。CoyoteOutPutStream中有一个属性ob(OutputBuffer),write方法调用的就是ob.writeBytes(),底层代码如下

    private void writeBytes(byte b[], int off, int len) throws IOException {          if (closed) {             return;         }          append(b, off, len);         bytesWritten += len;          if (doFlush) {             //每次把缓冲区的数据发送出去             flushByteBuffer();         }      }

        OutputBuffer中有个属性是bb(ByteChunk类型),里面有一个字节数组buff(8092kb),每次往缓冲区里添加数据的时候,就是往buff中写数据。代码中可以看到必须要满足doFlush的时候才会清空缓冲区,doFlush基本上就是在Servlet代码执行完前开发手动的调用OutputStream.flush()方法就会把它设置成true。这里就需要思考,什么时候会将buff中的数据放到socket中?

        ByteChunk有一个属性out(ByteOutPutChannel),本质上就是一个管道,实现了数据流向到哪里,里面有一个realWriteBytes方法。当我们调用的时候就会把数据往下游(可以先理解为往socket发,实际是往socketbuff中发,第二层缓存)发送。

public void realWriteBytes(ByteBuffer buf) throws IOException {        outputChunk.setBytes(buf,off,cnt);        coyoteResponse.doWrite(buf); }

这里面主要就是通过一个outputChunk来标记这些数据是要传输下去的,真正实现发送功能的就是coyoteResponse.dowrite。

        ByteChunk里面有append方法,来表示往buff中添加数据,当缓冲区大小满了之后,也会触发数据清空操作。还有一种情况就是上述说的,在缓冲区没满的时候,开发手动调用flush方法,也会执行数据清空下发操作。

        当我们调用outputStream.flush()方法的时候

                1.判断是否生成过响应头,有的话就不生了,没有的话说明是第一次发送,那么生成响应头。

                2.因为调用了flush方法,所以会调用ByteChunk的flushBuffer方法,将buff中的数据发出去,然后清空

                3.2中的数据其实是发送给另一个缓存(socketBuffer,但是这个缓存你是可以不用的,通过一些设置),SocketBuffer中也有一个ByteChunk,数据也是存放在这里面的,所以最后做的是将SocketBuffer中的数据发送到socket

        有一个属性useSocketBuffer,默认是false(如果要用必须你将socketBuffer设置大小超过500才会启用,这个可以自己去配置)

        我们最后调用的是coyoteResponse.doWrite方法,这里往下推调用的是outPutBuffer.doWrite方法(执行AbstractOutPutBuffer的逻辑)

                1.doWrite方法会先判断响应头是否已经发送,如果还没有,那么会先构造响应头然后发给socketBuffer

               2.发送完响应头,就会去判断你的数据到底是用Chunk还是ContentLength发送,对应着三个Filter(ContentLength->IdentityFilter,分块响应体->ChunkedFilter,不发送->VoidFilter)

        所以需要确定的是,到底是执行哪个Filter的逻辑,Tomcat的选择逻辑如下:

                Servlet中的所有代码执行完之后,就会调用response.finishResponse()->OutputBuffer.close()。close方法中会去判断响应体是否已经发送过了,如果一直没有发送过,说明缓冲区肯定是没满的,并且玩家没有执行过flush,那么第一缓冲区中的数据就是我们这次要发送的所有数据,所以缓冲区中的数据大小就是我们要的ContentLength大小,如果说在调用close之前已经发送过数据了,那么就会调用ChunkedFIlter的逻辑,比如我们自己调用flush,或者缓冲区满了,就会执行这个逻辑。

                在执行close方法的时候,会先将响应头的数据发送到socketBuffer,然后再将响应体的数据通过对应的OutputFilter发送,最后会调用OutputFilter的end方法,分块发送的时候会循环掉(因为有很多块),IdentityFilter就会一次性全部发送出去。

        上文就是Tomcat响应数据的过程

               

                

相关内容

热门资讯

安卓怎么删除原系统,释放设备潜... 手机用久了,是不是觉得内存不够用了?别急,别急,今天就来教你怎么在安卓手机上删除原系统,让你的手机焕...
王者小游戏推荐安卓系统,畅玩指... 手机里的小游戏是不是已经让你眼花缭乱,不知道该玩哪个了?别急,今天我就来给你推荐几款特别适合安卓系统...
安卓8.0系统是趋势嘛,引领未... 你有没有注意到,最近安卓系统更新换代的速度越来越快?这不,安卓8.0系统已经悄悄地来到了我们的身边。...
基于安卓系统有哪些,基于安卓系... 你有没有想过,手机的世界里,安卓系统就像是个万能的魔法师,它让无数的手机品牌和开发者有了施展才华的舞...
安卓美宜佳系统下载,轻松开启便... 你有没有发现,最近安卓手机上的一款新系统——美宜佳系统,简直火得一塌糊涂啊!这款系统不仅界面美观,功...
安卓系统的平板选内存,解锁高效... 你打算入手一块安卓系统的平板电脑,是不是有点儿犯难了?市面上那么多型号,内存大小也是五花八门,到底该...
安卓大屏做系统,创新体验与高效... 你有没有发现,现在手机屏幕越来越大,安卓大屏手机简直成了潮流!这不,最近我手头上的安卓大屏手机,让我...
kindle安卓系统转苹果,轻... 你有没有想过,把你的Kindle安卓系统转换成苹果系统,是不是会有一种全新的阅读体验呢?想象那些你珍...
安卓系统哪个手机最稳定,揭秘最... 你有没有想过,为什么你的手机有时候会突然卡顿,有时候又突然重启呢?是不是觉得安卓系统的手机稳定性是个...
南华寺攻略系统和安卓,安卓系统... 你有没有想过,去一个地方旅行,却因为信息不对称而感到头疼?别担心,今天我要给你安利一个神器——南华寺...
原生态的安卓系统,揭秘纯净操作... 亲爱的读者,你是否曾对手机系统产生过好奇?是不是在众多手机品牌中,对原生态的安卓系统情有独钟?今天,...
ios系统怎么传照片到安卓系统... 你是不是也有过这样的烦恼?手机里存了好多美美的照片,想分享给朋友,却发现他们用的是安卓系统,而你的手...
苹果安卓系统升学e网通,畅享智... 你有没有想过,为什么你的手机里装了那么多应用,却还是觉得不够用?今天,就让我带你一探究竟,看看苹果和...
erato手机怎么连接安卓系统... 你有没有想过,你的erato手机怎么才能和安卓系统完美连接呢?别急,今天就来给你详细揭秘这个神秘的过...
怎么安装安卓10系统,安卓10... 亲爱的读者们,你是否对安卓10系统充满了好奇,想要亲自体验一下它的魅力呢?别急,今天我就要手把手教你...
flymeicon是安卓系统吗... 你有没有注意到,手机界最近有个大热门——Flyme图标!是不是好奇这玩意儿是安卓系统的一部分呢?别急...
安卓免费虚拟系统软件,打造个性... 你有没有想过,在手机上体验不同的操作系统,而不需要更换手机?现在,就有这么神奇的安卓免费虚拟系统软件...
ios系统下载安卓软件下载,跨... 你有没有想过,为什么有时候你的iPhone上找不到那个超好用的安卓软件呢?别急,今天就来给你揭秘iO...
安卓系统手机今天黑屏,原因排查... 今天你的安卓手机突然黑屏了,是不是瞬间感觉心里一紧?别慌,让我来给你详细分析一下这个状况,帮你找出解...
一加9原生安卓系统,原生安卓魅... 你有没有听说最近一加手机的新款——一加9?这款手机可是火得一塌糊涂,尤其是它搭载的那个原生安卓系统,...