其实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开启了一个端口进行请求的监听。
分享到:
相关推荐
omcat是一个轻量级应用服务器,是支持运行Servlet/JSP应用程序的容器,运行在jvm上,绑定IP地址并监听TCP端口。 它是由Apache推出的一款免费开源的Servlet容器,可实现JavaWeb程序的装载,是配置JSP(Java Server ...
Tomcat请求过程 1、用户在浏览器中输入网址,请求被发送到本机端口8080,被在那里监听的 Connector获得; 2、Connector把该请求交给它所在的 Service的Engine (Container)来处理,然后等待Engine的回应; 3、请求在...
在tomcat中有两个监听的端口,一个是8080用于提供web服务,一个是8009用于监听来自于apache的请求。当apache收到jsp或者servlet请求时,就向tomcat 的8009端口发送请求,交由tomcat处理后,再返回给apache,由apache...
在tomcat中有两个监听的端口,一个是8080用于提供web服务,一个是8009用于监听来自于apache的请求。当apache收到jsp或者servlet请求时,就向tomcat 的8009端口发送请求,交由tomcat处理后,再返回给apache,由apache...
在tomcat中有两个监听的端口,一个是8080用于提供web服务,一个是8009用于监听来自于apache的请求。当apache收到jsp或者servlet请求时,就向tomcat 的8009端口发送请求,交由tomcat处理后,再返回给apache,由apache...
表示客户端和service之间的连接) port 指定服务器端要创建的端口号,并在这个断口监听来自客户端的请求 minProcessors 服务器启动时创建的处理请求的线程数 maxProcessors 最大可以创建的处理请求的线程数 ...
从tomcat配置文件中,我们可以看出,在启动tomcat的时候默认启动了3个端口,分别是8080(8443)、8009、8005。 8080(8443)端口 connectionTimeout=20000 redirectPort=8443> 这个应该是我们最熟悉的一个,平常...
其中对于xml使用jsoup进行处理,而对项目文件监听器侦听器是利用函数依附在请求,响应,上下文,会话Manger中等,当然这里侦听器仅实现了上下文。相关的服务器配置,例如生成上下文,即可以扫描webapps的目录实现,...
* 功能描述: 线程函数,创建一个单独线程用来接收客户端发来的请求,并将请求插入客户端链表中 * * 参数: 用于监听的socket描述符指针 lsnfd * * 返回值: NULL * * 作者: 胡士超 * * 完成日期: 2012.08....
众所周知,在unix下,非root用户不能监听1024以上的端口号,这个tomcat服务器就没办法绑定在80端口下。所以这里需要使用linux的端口转发机制,把到80端口的服务请求都转到8080端口上。 在root账户下面运行一下命令:...
当用户发送第一次请求的时候,验证用户登录,创建一个该qq号和服务器端保持通讯连接得线程,启动该通讯线程,通讯完毕,关闭Scoket。 QQ客户端登录界面,中部有三个JPanel,有一个叫选项卡窗口管理。还可以更新...
服务器上 nginx + tomcat ,其中 nginx 监听 80 端口, tomcat 监听 8080 端口。 因为对前端不熟悉,以为用 ajax 就可以不需要 callback ,然而前端的同学说不跨域的情况下才不需要 callback ,让我在返回的 json 里...
21个目标文件 摘要:JAVA源码,媒体网络,山寨QQ,Java聊天程序 Java编写的山寨QQ,多人聊天+用户在线,程序分服务端和客户端,典型C/S结构, 当用户发送第一次请求的时候,验证用户登录,创建一个该qq号和服务器端保持...