Tomcat的Connector测试类

    public static void main(String[] args) throws Exception {
        Connector connector = new Connector("HTTP/1.1");
        connector.setPort(8080);
        connector.init();//protocolHandler.init(); 这里主要是绑定8080端口的ServerSocketChannel
        /**
         * 替换init的Adapter初始化
         * adapter = new CoyoteAdapter(this); //连接Service的桥梁,通过他将request response 传入到webapps 的应用当中
         * protocolHandler.setAdapter(adapter);
         * Adapter是对读写io的数据与业务处理的适配
         */
        connector.getProtocolHandler().setAdapter(new Adapter() {
            @Override
            public void service(Request req, Response res) throws Exception {
                res.setStatus(200);
                res.doWrite(ByteBuffer.wrap("Hello World...".getBytes()));
            }

            @Override
            public boolean prepare(Request req, Response res) throws Exception {
                return false;
            }

            @Override
            public boolean asyncDispatch(Request req, Response res, SocketEvent status) throws Exception {
                return false;
            }

            @Override
            public void log(Request req, Response res, long time) {
            }

            @Override
            public void checkRecycled(Request req, Response res) {
            }

            @Override
            public String getDomain() {
                return null;
            }
        });
        connector.start();
        System.in.read();
    }

浏览器输入http://127.0.0.1:8080/ 页面返回Hello World...

Connector的构造函数中使用setProtocol进行协议的选择创建ProtocolHandler

public Connector(String protocol) {
        setProtocol(protocol);
        // Instantiate protocol handler
        ProtocolHandler p = null;
        try {
            Class<?> clazz = Class.forName(protocolHandlerClassName);
            p = (ProtocolHandler) clazz.getConstructor().newInstance();
        } catch (Exception e) {
            log.error(sm.getString(
                    "coyoteConnector.protocolHandlerInstantiationFailed"), e);
        } finally {
            this.protocolHandler = p;
        }
        //省略非关键代码....
}
public void setProtocol(String protocol) {
    boolean aprConnector = AprLifecycleListener.isAprAvailable() &&
            AprLifecycleListener.getUseAprConnector();
    if ("HTTP/1.1".equals(protocol) || protocol == null) {
        if (aprConnector) {
            setProtocolHandlerClassName("org.apache.coyote.http11.Http11AprProtocol");
        } else {
            setProtocolHandlerClassName("org.apache.coyote.http11.Http11NioProtocol");
        }
    } else if ("AJP/1.3".equals(protocol)) {
        if (aprConnector) {
            setProtocolHandlerClassName("org.apache.coyote.ajp.AjpAprProtocol");
        } else {
            setProtocolHandlerClassName("org.apache.coyote.ajp.AjpNioProtocol");
        }
    } else {
        setProtocolHandlerClassName(protocol);
    }
}

connector.init();

@Override
protected void initInternal() throws LifecycleException {
    ...  
    adapter = new CoyoteAdapter(this);
    protocolHandler.setAdapter(adapter);
    ...
    try {
        protocolHandler.init();//bind() serverSock.socket().bind(addr,getAcceptCount());
    } catch (Exception e) {
        throw new LifecycleException(
                sm.getString("coyoteConnector.protocolHandlerInitializationFailed"), e);
    }
    ...
}

connector.start();

@Override
protected void startInternal() throws LifecycleException {
    ...
    try {
        protocolHandler.start();//开始接受tcp请求连接
    } catch (Exception e) {
        throw new LifecycleException(
                sm.getString("coyoteConnector.protocolHandlerStartFailed"), e);
    }
    ...
}

通过上述步骤中我们发现connector 中大部分操作都是基于protocolHandler (默认不启动apr我们使用的是org.apache.coyote.http11.Http11NioProtocol)。我们脑子里会出现大体的流程 protocolHandler 创建服务器套接字并将其绑定到指定的本地8080端口,侦听并接受到此套接字的连接,将读取的数据封装为request 创建response,传入到Adapter 进行业务处理(写入响应码:200 写入body:Hello World...)将response中通过socket返回客户端。这个只是可以简单的描述流程,这个过程中涉及到nio的实现,线程模型的设计,长短连接的控制,如何通过优化提高并发?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值