Tomcat源码分析 建立Http通信的过程

Tomcat的http通信由connector模块完成。connector启动之后初始化线程用来监听指定端口(默认是8080),每次接受到连接会通过线程池产生socket线程处理通信。整个流程很清晰,这里指列出主要的代码。主要涉及到下面几个类:

Connector,Http11Protocol,JIoEndpoint,SocketWrapper,DefaultServerSocketFactory

1.      server.xml中配置:

    <Connector port="8090" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />

2.      构造Http通信的connector

Connector构造时传入"HTTP/1.1",通过反射构造Http11Protocol

   public  Connector(String protocol) {
           setProtocol(protocol);
            Class<?> clazz = Class.forName(protocolHandlerClassName);
            this.protocolHandler = (ProtocolHandler) clazz.newInstance();
   }

    public  void setProtocol(String protocol) {
            if ("HTTP/1.1".equals(protocol)) {
                setProtocolHandlerClassName(org.apache.coyote.http11.Http11Protocol");
            } else if ("AJP/1.3".equals(protocol)) {
                setProtocolHandlerClassName ("org.apache.coyote.ajp.AjpProtocol");
            } 
    }

    public  Http11Protocol() {
        endpoint = new JIoEndpoint();
    }


3.      初始化监听socket

protected void startInternal() throws LifecycleException {
            protocolHandler.init();
            protocolHandler.start();
}

public  void protocolHandler .init() throws Exception {
    ((JIoEndpoint)endpoint).setHandler(cHandler);        
        try {
	//这里提供了socketFactory的扩展,可以载入第三方的socketFactory。
            if (isSSLEnabled()) {
                sslImplementation =
                    SSLImplementation.getInstance(sslImplementationName);
                socketFactory = sslImplementation.getServerSocketFactory();
                ((JIoEndpoint)endpoint).setServerSocketFactory(socketFactory);
            } else if (socketFactoryName != null) {
                socketFactory = (ServerSocketFactory) Class.forName(socketFactoryName).newInstance();
                ((JIoEndpoint)endpoint).setServerSocketFactory(socketFactory);
            }
        } catch (Exception ex) {
            log.error(sm.getString("http11protocol.socketfactory.initerror"),
                      ex);
            throw ex;
        }
     endpoint.init(); 
}

public  void endpoint .init()
        throws Exception {
         if (serverSocketFactory == null) {
            	serverSocketFactory = ServerSocketFactory.getDefault();
        	}
           serverSocket = serverSocketFactory.createSocket(getPort(), getBacklog());
    }


4.      新建线程,启动监听

    public  void protocolHandler .start() throws Exception {
            endpoint.start();
    }

    public  void endpoint.start() throws Exception {
            // Create worker collection
            if (getExecutor() == null) {
                createExecutor();
            }
            // Start acceptor threads
            for (int i = 0; i < acceptorThreadCount; i++) {
                Thread acceptorThread = new Thread(new Acceptor(), getName() + "-Acceptor-" + i);
                acceptorThread.start();
            }
        }
    }

5. 处理新连接

Accept类的run中,每次监听到新连接会执行processSocket(socket),通过executor把新连接放到独立的线程中。然后执行SocketProcessor.run。

protected boolean processSocket(Socket socket) {
            SocketWrapper<Socket> wrapper = new SocketWrapper<Socket>(socket);
            wrapper.setKeepAliveLeft(getMaxKeepAliveRequests());
            getExecutor().execute(new SocketProcessor(wrapper));
        return true;
}

public  void SocketProcessor.run() {
        	    if ( (state != SocketState.CLOSED) ) {
        	        state = (status==null)?handler.process(socket):handler.process(socket,status);
        	    } 
   }

handler在初始化时设置((JIoEndpoint)endpoint).setHandler(cHandler);

以上分析了从建立监听到处理新连接的过程。通信模块通过包org.apache.tomcat.util.net来实现,在类JIoEndpoint中通过interfaceHandler开放HTTP协议解析接口。HTTP协议解析会在后面的文章中分析。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值