到你呢?解析应用层协议(三)

到你呢?解析应用层协议

前言

如图,上节聊到Accrptor监听请求后,注册到队列,Poller线程去轮询队列,包装创建SocketProcessor丢到线程池。

在这里插入图片描述

看一下线程池处理以及后续调用具体的方法调用

处理

源码分析

下面进行源码的分析:

运行SocketProcessorBase的run方法

public final void run() {
    synchronized (socketWrapper) {
        //调用子类SocketProcessor的doRun
        doRun();
    }
}

调用实现类SocketProcessor的doRun

@Override
protected void doRun() {
				。。。。。
    try {
        int handshake = -1;
        try {
            // handshake 是用来处理 https 的握手过程的,
            // 如果是 http 不需要该握手阶段,下面会将该标志设置为 0, 表示握手已经完成
            // 是否已经握手成功
            if (socketWrapper.getSocket().isHandshakeComplete()) {
                handshake = 0;
            } else 
              。。。。
            }
        }
        if (handshake == 0) {
            SocketState state = SocketState.OPEN;
            // Process the request from this socket
            if (event == null) {
                // 认是读事件处理
                // 这里的getHandler()返回AbstractProtocol.ConnectionHandler,
                // 在Http11NioProtocol对象构造期间被创建并设置到当前NioEndpoint对象
                state = getHandler().process(socketWrapper, SocketEvent.OPEN_READ);
            } else {
                // 响应指定事件处理
                // 这里的getHandler()返回AbstractProtocol.ConnectionHandler,
                // 在Http11NioProtocol对象构造期间被创建并设置到当前NioEndpoint对象
                state = getHandler().process(socketWrapper, event);
            }
            if (state == SocketState.CLOSED) {
                poller.cancelledKey(getSelectionKey(), socketWrapper);
            }
        }
   。。。。
}

getHandler()拿的是AbstractProtocol内部类ConnectionHandler

public SocketState process(SocketWrapperBase<S> wrapper, SocketEvent status) {
    。。。。。。
    try {
        if (processor == null) {
        		///协议可能升级
            String negotiatedProtocol = wrapper.getNegotiatedProtocol();
            if (negotiatedProtocol != null && negotiatedProtocol.length() > 0) {
                UpgradeProtocol upgradeProtocol = getProtocol().getNegotiatedProtocol(negotiatedProtocol);
                if (upgradeProtocol != null) {
                    //协议升级如果配置了类UpgradeProtocol
                    processor = upgradeProtocol.getProcessor(wrapper, getProtocol().getAdapter());
                    if (getLog().isDebugEnabled()) {
                        getLog().debug(sm.getString("abstractConnectionHandler.processorCreate", processor));
           。。。。
        }
        if (processor == null) {
            // 从recycledProcessors可循环processors中获取processor
            processor = recycledProcessors.pop();
            if (getLog().isDebugEnabled()) {
                getLog().debug(sm.getString("abstractConnectionHandler.processorPop", processor));
            }
        }
        //创建一个新的Http11Processor
        if (processor == null) {
            processor = getProtocol().createProcessor();
            register(processor);
            if (getLog().isDebugEnabled()) {
                getLog().debug(sm.getString("abstractConnectionHandler.processorCreate", processor));
            }
        }
				,。。。
        do {
        		//循环
            //抽象类AbstractProcessorLight的process方法
            state = processor.process(wrapper, status);
						。。。。。。
             } while ( state == SocketState.UPGRADING);

}

processor.process这里是去处理应用层的小编。

先看一下继承关系。

在这里插入图片描述

Processor类:

所有协议的处理器的通用接口。

AbstractProcessorLight:

这是一个轻量级抽象处理器实现,旨在作为从轻量级升级处理器到 HTTPAJP 处理器的所有处理器实现的基础。

public SocketState process(SocketWrapperBase<?> socketWrapper, SocketEvent status)
        throws IOException {
    //处理不在标准HTTP模式下的正在处理中的请求。
    //目前使用的包括Servlet 3.0异步和HTTP升级连接
    //将来可能会增加更多的用途。这些通常以HTTP请求开始。
    SocketState state = SocketState.CLOSED;
    Iterator<dispatchType> dispatches = null;
    do {
        。。。。
        } else if (status == SocketEvent.OPEN_READ) {
            //可读状态,认Http11Processor的实现的service
            state = service(socketWrapper);
        } 
      。。。。
    } while (state == SocketState.ASYNC_END ||
            dispatches != null && state != SocketState.CLOSED);

    return state;
}

‼️到了关键的一步,Http11Processor去解析应用层的协议

public SocketState service(SocketWrapperBase<?> socketWrapper)
    throws IOException {
		。。。。。
    // Setting up the I/O
    //初始化输入输出
    setSocketWrapper(socketWrapper);
		。。。。。
    while (!getErrorState().isError() && keepAlive && !isAsync() && upgradetoken == null &&
            sendfileState == SendfileState.DONE && !endpoint.isPaused()) {
        // Parsing the request header
        try {
            //解析请求的第一行也就是method、uri以及protocol(GET /S2_3_16_1/hello.action HTTP/1.1),
            // 将相应的值设到request实例中
            if (!inputBuffer.parseRequestLine(keptAlive)) {
                。。。。
            }
            。。。
                //parseHeaders()解析HTTP头将内容(host,ua,connect…)设置到headers实例中
                if (!http09 && !inputBuffer.parseHeaders()) {
              。。。
            }
        } 。。。。
        if (getErrorState().isIoAllowed()) {
         
            try {
                //各种解析请求,组装request
                //通过prepareRequest方法组装request filter,用于处理http消息体
                prepareRequest();
            。。。
        // Process the request in the adapter
        if (getErrorState().isIoAllowed()) {
            try {
                rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
                //获取CoyoteAdapter,调用其service方法
                getAdapter().service(request, response);
        。。。。
     
}

回顾一下整体的方法调用,最后交给适配器处理,getAdapter().service(request, response)。

在这里插入图片描述

总结

通过这二节内容,我们可以清楚了看到Tomcat如何接收请求,到最后适配转到容器。后面将要讲到适配器处理的细节!!!

相关文章

显卡天梯图2024最新版,显卡是电脑进行图形处理的重要设备,...
初始化电脑时出现问题怎么办,可以使用win系统的安装介质,连...
todesk远程开机怎么设置,两台电脑要在同一局域网内,然后需...
油猴谷歌插件怎么安装,可以通过谷歌应用商店进行安装,需要...
虚拟内存这个名词想必很多人都听说过,我们在使用电脑的时候...