`
zddava
  • 浏览: 243027 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Tomcat NIO源代码分析(三) -- Protocol和Processor

阅读更多
现在请求到了Protocol(Http11NioProtocol)的#process()方法了,由于方法较长,很多代码没有列出:

	public SocketState process(NioChannel socket) {
		// 得到Processor
		Http11NioProcessor processor = connections.remove(socket);
		try {
			if (processor == null) {
				processor = recycledProcessors.poll();
			}
			if (processor == null) {
				processor = createProcessor();
			}

			// 配置processor是否SSL:略
			......

			// 重要:调用Processor的#process()方法
			SocketState state = processor.process(socket);

			// 对长连接的支持:略
			if (state == SocketState.LONG) {
				......
			}
			if (state == SocketState.LONG || state == SocketState.ASYNC_END) {
				// Already done all we need to do.
			} else if (state == SocketState.OPEN) {// 一般的keep-alive的请求都回到这里
				// 开始回收Processor
				release(socket);
				// 如果keep-alive,那么将SocketChannel继续加到Poller中等待
				socket.getPoller().add(socket);
			} else {
				// 回收Processor
				release(socket);
			}
			return state;

		} catch(XXXException){
			// 略过异常处理
			......
		}
		
		// 做一些回收工作
		connections.remove(socket);
		processor.recycle();
		recycledProcessors.offer(processor);
		return SocketState.CLOSED;
	}


这里很明显,最重要的是对Processor的#process()的调用,直接上代码,当然,方法太长也略过了很多部分。另外对请求的byte[]的解析就不上代码了,太长了,主要的方式就是byte[]循环的方式,这也是为了提高效率的考虑,毕竟使用字符串和byte相比还是要慢的。

	public SocketState process(NioChannel socket) throws IOException {
		RequestInfo rp = request.getRequestProcessor();
		rp.setStage(org.apache.coyote.Constants.STAGE_PARSE);

		// Setting up the socket
		this.socket = socket;
		inputBuffer.setSocket(socket);
		outputBuffer.setSocket(socket);
		inputBuffer.setSelectorPool(endpoint.getSelectorPool());
		outputBuffer.setSelectorPool(endpoint.getSelectorPool());

		// Error flag
		error = false;
		keepAlive = true;
		comet = false;

		long soTimeout = endpoint.getSoTimeout();
		int keepAliveTimeout = endpoint.getKeepAliveTimeout();

		boolean keptAlive = false;
		boolean openSocket = false;
		boolean recycle = true;
		final KeyAttachment ka = (KeyAttachment) socket.getAttachment(false);

		while (!error && keepAlive && !comet && !isAsync() && !endpoint.isPaused()) {
			// always default to our soTimeout
			ka.setTimeout(soTimeout);
			// Parsing the request header
			try {
				if (!disableUploadTimeout && keptAlive && soTimeout > 0) {
					socket.getIOChannel().socket().setSoTimeout((int) soTimeout);
				}
				// 这里将Socket的数据读入到读缓冲区,nRead = socket.read(socket.getBufHandler().getReadBuffer());
				// 并且将协议和请求的URI解析出来
				if (!inputBuffer.parseRequestLine(keptAlive)) {
					// 略过非正常情况的处理
				}
				keptAlive = true;
				// 这一步是解析请求的Header,Tomcat的解析是直接基于byte[]去逐个循环的,可以好好学下
				if (!inputBuffer.parseHeaders()) {
					// 略过非正常情况的处理
				}
				request.setStartTime(System.currentTimeMillis());
				if (!disableUploadTimeout) {
					socket.getIOChannel().socket().setSoTimeout(timeout);
				}
			} catch(XXXException){
				// 略过异常处理
				......
			}

			if (!error) {
				rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE);
				try {
					// 设定请求处理的一些Filters
					prepareRequest();
				} catch(XXXException){
					// 略过异常处理
					......
				}
			}

			if (maxKeepAliveRequests == 1)
				keepAlive = false;
			if (maxKeepAliveRequests > 0 && ka.decrementKeepAlive() <= 0)
				keepAlive = false;

			// Process the request in the adapter
			if (!error) {
				try {
					rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
					// 这里就是调用CoyoteAdapter去继续请求了,此时请求会脱离Connctor层进入Engine层了
					// 进入Tomcat请求处理PipeLine的下一段管道了
					adapter.service(request, response);

					if (keepAlive && !error) { // Avoid checking twice.
						error = response.getErrorException() != null
								|| statusDropsConnection(response.getStatus());
					}
					// 长连接的支持:略
					......

				} catch(XXXException){
					// 略过异常处理
					......
				}
			}

			// 收尾和回收工作:略

		}// while

		rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);
		if (error || endpoint.isPaused()) {
			recycle();
			return SocketState.CLOSED;
		} else if (comet || isAsync()) {
			return SocketState.LONG;
		} else {
			if (recycle) {
				recycle();
			}
			// return (openSocket) ? (SocketState.OPEN) : SocketState.CLOSED;
			return (openSocket) ? (recycle ? SocketState.OPEN : SocketState.LONG) : SocketState.CLOSED;
		}

	}


这段代码有分4个部分需要关注下。
(1) 对inputBuffer的#parseRequestLine()的调用,这里主要就是读入Socket的数据并且解析出请求的URI;
(2) 对inputBuffer的#parseHeaders()的调用,这里就是读取请求中的请求头了;
(3) #prepareRequest()的调用,这里主要是对前两步得到的数据进行分析使用,构建处理请求的上下文属性,并且如果请求的transfer-encoding域有值,需要配置相应的Filter去处理。默认有IdentityInputFilter,ChunkedInputFilter,VoidInputFilter,BufferedInputFilter四种;
(4) 对CoyoteAdapter的#service()的调用,这里就准备进入PipeLine的下一段管道了。

全文完。
1
0
分享到:
评论
1 楼 fengyonglei 2011-11-07  
好文章 谢谢分享

相关推荐

    xnio-nio-3.8.4.Final-API文档-中英对照版.zip

    赠送源代码:xnio-nio-3.8.4.Final-sources.jar; 赠送Maven依赖信息文件:xnio-nio-3.8.4.Final.pom; 包含翻译后的API文档:xnio-nio-3.8.4.Final-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:org....

    xnio-nio-3.8.0.Final-API文档-中文版.zip

    赠送源代码:xnio-nio-3.8.0.Final-sources.jar; 赠送Maven依赖信息文件:xnio-nio-3.8.0.Final.pom; 包含翻译后的API文档:xnio-nio-3.8.0.Final-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.jboss.xnio:...

    xnio-nio-3.8.4.Final-API文档-中文版.zip

    赠送源代码:xnio-nio-3.8.4.Final-sources.jar; 赠送Maven依赖信息文件:xnio-nio-3.8.4.Final.pom; 包含翻译后的API文档:xnio-nio-3.8.4.Final-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.jboss.xnio:...

    xnio-nio-3.8.0.Final-API文档-中英对照版.zip

    赠送源代码:xnio-nio-3.8.0.Final-sources.jar; 赠送Maven依赖信息文件:xnio-nio-3.8.0.Final.pom; 包含翻译后的API文档:xnio-nio-3.8.0.Final-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:org....

    httpcore-nio-4.4.15-API文档-中文版.zip

    赠送源代码:httpcore-nio-4.4.15-sources.jar 包含翻译后的API文档:httpcore-nio-4.4.15-javadoc-API文档-中文(简体)版.zip 对应Maven信息:groupId:org.apache.httpcomponents,artifactId:httpcore-nio,...

    Tomcat8源代码

    本文将深入探讨Tomcat 8的源代码,帮助读者理解其工作原理,以便更好地优化和定制自己的服务器环境。 1. **目录结构** Apache Tomcat 8的源代码目录结构清晰,主要分为以下几个部分: - `conf`:存放服务器配置...

    httpcore-nio-4.4.6-API文档-中文版.zip

    赠送源代码:httpcore-nio-4.4.6-sources.jar 包含翻译后的API文档:httpcore-nio-4.4.6-javadoc-API文档-中文(简体)版.zip 对应Maven信息:groupId:org.apache.httpcomponents,artifactId:httpcore-nio,...

    apache-tomcat-8.5.64-windows-x64.zip

    Apache Tomcat 8.5是Java Servlet和JavaServer Pages(JSP)的开源Web应用程序服务器,由Apache软件基金会开发和维护。它是一个轻量级应用服务器,特别适用于部署Java EE Web应用程序。在这个“apache-tomcat-8.5.64...

    tomcat6 源代码

    Apache Tomcat 6是一款广泛应用的开源Java Servlet容器...通过深入学习和研究Tomcat6的源代码,开发者不仅可以掌握Servlet容器的工作原理,还能提升解决实际问题的能力,为构建高效、稳定的Java Web应用打下坚实基础。

    apache-tomcat-7.0.88-src.tar

    在本文中,我们将深入探讨`apache-tomcat-7.0.88-src.tar`这个源代码包,了解其核心组件、工作原理以及如何通过源代码学习和定制Tomcat。 首先,`apache-tomcat-7.0.88-src.tar`是一个包含Apache Tomcat 7.0.88版本...

    apache-tomcat-8.5.97-windows-x.zip

    Apache Tomcat 是一个开源软件应用服务器,主要用于部署和运行Java Servlet和JavaServer Pages(JSP)应用程序。这个压缩包文件 "apache-tomcat-8.5.97-windows-x.zip" 包含了Apache Tomcat 8.5.97 版本在Windows...

    httpcore-nio-4.4.10-API文档-中英对照版.zip

    赠送源代码:httpcore-nio-4.4.10-sources.jar; 赠送Maven依赖信息文件:httpcore-nio-4.4.10.pom; 包含翻译后的API文档:httpcore-nio-4.4.10-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:org....

    tomcat7源代码

    《深入剖析Tomcat7源代码》 Tomcat7是一款广泛使用的开源Java Servlet容器,它实现了Java EE中的Web应用规范,包括Servlet、JSP和EL(Expression Language)等。本资源包含Tomcat7的源代码以及运行所需的jar包,...

    httpcore-nio-4.4.15-API文档-中英对照版.zip

    赠送源代码:httpcore-nio-4.4.15-sources.jar 包含翻译后的API文档:httpcore-nio-4.4.15-javadoc-API文档-中文(简体)-英语-对照版.zip 对应Maven信息:groupId:org.apache.httpcomponents,artifactId:...

    tomcat-native-1.2.25-src-build

    "tomcat-native-1.2.25-src-build" 指的是该扩展的源代码版本1.2.25,用于编译生成适用于不同操作系统的本地库文件。 【编译过程】:下载的源码包"tomcat-native-1.2.25-src-build"需要经过编译才能生成适用于目标...

    最新版windows apache-tomcat-9.0.54-windows-x64.zip

    Apache Tomcat是一款开源的Java应用服务器,主要用于运行Java Servlet和JavaServer Pages(JSP)技术。这个最新的版本,即apache-tomcat-9.0.54,是针对Windows操作系统设计的64位版本,提供了在Windows环境下部署和...

    apache-tomcat-9.0.74-windows-x64

    Apache Tomcat 9.0.74 是一个广泛使用的开源软件,它是一个实现了Java Servlet、JavaServer Pages(JSP)和Java EE的Web应用程序容器。这个版本是专门为Windows x64平台设计的,确保在64位操作系统上高效运行。在...

    httpcore-nio-4.4.10-API文档-中文版.zip

    赠送源代码:httpcore-nio-4.4.10-sources.jar; 赠送Maven依赖信息文件:httpcore-nio-4.4.10.pom; 包含翻译后的API文档:httpcore-nio-4.4.10-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache....

    Tomcat 8源代码 Servlet源代码

    源代码分析对于理解Tomcat的工作原理、优化性能或进行自定义扩展非常有价值。这里的“简单实用”可能是指通过研究源码,开发者可以更直观地了解Web服务器内部机制,从而更好地应用在实际项目中。 **Tomcat 8源代码...

    手写 tomcat nio

    在手写Tomcat NIO时,我们需要创建并管理这些SocketChannel,以接收和响应客户端请求。 2. **选择器(Selector)**:选择器是NIO的核心组件,它允许我们监控多个通道的事件(如连接就绪、数据可读或可写等)。通过...

Global site tag (gtag.js) - Google Analytics