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

Tomcat请求处理(一) -- 服务器端口监听

阅读更多
其实tomcat在哪个类中监听请求的代码很容易找到:

在org.apache.tomcat.util.net.JIoEndpoint$Acceptor#run()中的这么一句:

Socket socket = serverSocketFactory.acceptSocket(serverSocket);

可是ServerSocketFactory是个抽象类,我还是很想知道整个过程的来龙去脉的。

那就要还是从初始化开始,当Tomcat的HTTP Connector初始化,会org.apache.coyote.http11.Http11Protocol调用它的init()方法。

在这个init()方法中,又调用了org.apache.tomcat.util.net.JIoEndpoint#init(),代码如下:

	public void init() throws Exception {
		if (initialized)
			return;

		// acceptor线程的数量
		if (acceptorThreadCount == 0) {
			acceptorThreadCount = 1;
		}

		// 返回DefaultServerSocketFactory类对象做为ServerSocketFactory的实例
		if (serverSocketFactory == null) {
			serverSocketFactory = ServerSocketFactory.getDefault();
		}
		// 创建ServerSocket
		if (serverSocket == null) {
			try {
				if (address == null) {
					serverSocket = serverSocketFactory.createSocket(port, backlog);
				} else {
					serverSocket = serverSocketFactory.createSocket(port, backlog, address);
				}
			} catch (BindException be) {
				if (address == null)
					throw new BindException(be.getMessage() + "<null>:" + port);
				else
					throw new BindException(be.getMessage() + " " + address.toString() + ":" + port);
			}
		}

		initialized = true;

	}


现在已经知道了文章最初提到的serverSocketFactory引用的是一个DefaultServerSocketFactory类的对象。并且在这里创建了一个ServerSocket对象。

当Tomcat初始化完毕执行一些列开启服务的动作时,HTTP Connector也会执行它的start()方法,然后会调用Http11Protocol的start()方法,最后程序会执行到JIoEndpoint#start(),下面来看一下:

	public void start() throws Exception {
		if (!initialized) {
			init();
		}

		if (!running) {
			running = true;
			paused = false;

			// 先初始化一些Worker
			if (executor == null) {
				workers = new WorkerStack(maxThreads);
			}

			// 开启Acceptor线程,默认只开启一个Acceptor线程,见JIoEndpoint#init()。
			for (int i = 0; i < acceptorThreadCount; i++) {
				Thread acceptorThread = new Thread(new Acceptor(), getName() + "-Acceptor-" + i);
				acceptorThread.setPriority(threadPriority);
				acceptorThread.setDaemon(daemon);
				acceptorThread.start();
			}
		}
	}


这样,就开启了一个Acceptor线程,接下来看一看这个线程做了什么东西。

		public void run() {
			while (running) {

				while (paused) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
					}
				}

				try {
					// 开始监听端口
					Socket socket = serverSocketFactory.acceptSocket(serverSocket);
					// 初始化Socket
					serverSocketFactory.initSocket(socket);
					if (!processSocket(socket)) {
						try {
							socket.close();
						} catch (IOException e) {
						}
					}
				} catch (IOException x) {
					if (running)
						log.error(sm.getString("endpoint.accept.fail"), x);
				} catch (Throwable t) {
					log.error(sm.getString("endpoint.accept.fail"), t);
				}
			}

		}


至此,Tomcat开启了一个端口进行请求的监听。
分享到:
评论
1 楼 hdwmp123 2014-07-17  

相关推荐

Global site tag (gtag.js) - Google Analytics