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(),代码如下: 

Java代码    收藏代码
  1. public void init() throws Exception {  
  2.     if (initialized)  
  3.         return;  
  4.   
  5.     // acceptor线程的数量  
  6.     if (acceptorThreadCount == 0) {  
  7.         acceptorThreadCount = 1;  
  8.     }  
  9.   
  10.     // 返回DefaultServerSocketFactory类对象做为ServerSocketFactory的实例  
  11.     if (serverSocketFactory == null) {  
  12.         serverSocketFactory = ServerSocketFactory.getDefault();  
  13.     }  
  14.     // 创建ServerSocket  
  15.     if (serverSocket == null) {  
  16.         try {  
  17.             if (address == null) {  
  18.                 serverSocket = serverSocketFactory.createSocket(port, backlog);  
  19.             } else {  
  20.                 serverSocket = serverSocketFactory.createSocket(port, backlog, address);  
  21.             }  
  22.         } catch (BindException be) {  
  23.             if (address == null)  
  24.                 throw new BindException(be.getMessage() + "<null>:" + port);  
  25.             else  
  26.                 throw new BindException(be.getMessage() + " " + address.toString() + ":" + port);  
  27.         }  
  28.     }  
  29.   
  30.     initialized = true;  
  31.   
  32. }  


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

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

Java代码    收藏代码
  1. public void start() throws Exception {  
  2.     if (!initialized) {  
  3.         init();  
  4.     }  
  5.   
  6.     if (!running) {  
  7.         running = true;  
  8.         paused = false;  
  9.   
  10.         // 先初始化一些Worker  
  11.         if (executor == null) {  
  12.             workers = new WorkerStack(maxThreads);  
  13.         }  
  14.   
  15.         // 开启Acceptor线程,默认只开启一个Acceptor线程,见JIoEndpoint#init()。  
  16.         for (int i = 0; i < acceptorThreadCount; i++) {  
  17.             Thread acceptorThread = new Thread(new Acceptor(), getName() + "-Acceptor-" + i);  
  18.             acceptorThread.setPriority(threadPriority);  
  19.             acceptorThread.setDaemon(daemon);  
  20.             acceptorThread.start();  
  21.         }  
  22.     }  
  23. }  


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

Java代码    收藏代码
  1. public void run() {  
  2.     while (running) {  
  3.   
  4.         while (paused) {  
  5.             try {  
  6.                 Thread.sleep(1000);  
  7.             } catch (InterruptedException e) {  
  8.             }  
  9.         }  
  10.   
  11.         try {  
  12.             // 开始监听端口  
  13.             Socket socket = serverSocketFactory.acceptSocket(serverSocket);  
  14.             // 初始化Socket  
  15.             serverSocketFactory.initSocket(socket);  
  16.             if (!processSocket(socket)) {  
  17.                 try {  
  18.                     socket.close();  
  19.                 } catch (IOException e) {  
  20.                 }  
  21.             }  
  22.         } catch (IOException x) {  
  23.             if (running)  
  24.                 log.error(sm.getString("endpoint.accept.fail"), x);  
  25.         } catch (Throwable t) {  
  26.             log.error(sm.getString("endpoint.accept.fail"), t);  
  27.         }  
  28.     }  
  29.   
  30. }  


至此,Tomcat开启了一个端口进行请求的监听。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值