tomcat 的原理

这个问题,可以参考“为什么使用Servlet” 中的解答;

其中提到,在BS中如何运行serversocket 的服务类(假设命名为ServTomcat),

说到底,就是在这个ServTomcat类中main 入口方法来启动一个线程处理客户端请求;


该线程用来等待接收客户连接,当有客户连接sever.accept(),则得到socket 并且可以得到相应的流 bufferreader


在ServTomcat 类 (伪servlet)中处理web 上的http请求,从浏览器到服务端的一次请求都会遵循http协议, 或者说在网络上tcp协议,也就是我们所说socket 来处理客户端与服务器交互。


根据http协议规则[请求行,消息报头,请求正文],从流中可以得到 

GET|Post方法 、HTTP1.1 等数据信息


最后将这些信息用打印流方式输出给浏览器;

printstream out = socket.getoutputstream();

out.println("http/1.0 200 ok");

out.println("<html>....</html>");


out.close();

关闭



其中注意,为了让服务器一直处于启动状态,该线程要一直处于运行状态 run() { while(true){ }}。


贴上一段代码,便于参与;一个简单的tomcat


package org.great;


import java.io.*;

import java.net.*;

@author ccq

public class WebServer

{

public static void main(String args[])

{

int i=1, PORT=8080;

ServerSocket server=null;

Socket client=null;

try 

{

server=new ServerSocket(PORT);  

System.out.println("Web Server is listening on port "+server.getLocalPort());

for (;;)

{

client=server.accept();  //接受客户机的连接请求

new ConnectionThread(client,i).start();  

i++;

}

}

catch (Exception e) {System.out.println(e);}

}

}

/* ConnnectionThread类完成与一个Web浏览器的通信  */

class ConnectionThread extends Thread

{

Socket client;  //连接Web浏览器的socket字

int counter;  //计数器

public ConnectionThread(Socket cl,int c) 

{

client=cl;

counter=c;

}

public void run()   //线程体

{

try

{

String destIP=client.getInetAddress().toString();  //客户机IP地址

int destport=client.getPort();                   //客户机端口号

System.out.println("Connection "+counter+":connected to "+destIP+" on port "+destport+".");

PrintStream outstream=new PrintStream(client.getOutputStream());

DataInputStream instream=new DataInputStream(client.getInputStream());

String inline=instream.readLine();  //读取Web浏览器提交的请求信息

System.out.println("Received:"+inline);

if (getrequest(inline))

{      //如果是GET请求

String filename=getfilename(inline);

File file=new File(filename);

if (file.exists())

{  //若文件存在,则将文件送给Web浏览器

System.out.println(filename+" requested.");

outstream.println("HTTP/1.0 200 OK");

outstream.println("MIME_version:1.0");

outstream.println("Content_Type:text/html");

int len=(int)file.length();

outstream.println("Content_Length:"+len);

outstream.println("");

sendfile(outstream,file);  //发送文件

outstream.flush();

}

else

{  //文件不存在时

String msg1="<html><head><title>Not Found</title></head><body><h1>hah Error 404-file not found</h1></body></html>";

outstream.println("HTTP/1.0 404 no found");

outstream.println("Content_Type:text/html");

outstream.println("Content_Length:"+msg1.length()+2);

outstream.println("");

outstream.println(msg1);

outstream.flush();

}

}

//instream.close();

//outstream.close();

long m1=1;    //延时

while (m1<11100000) {m1++;} 

client.close();

}

catch (IOException e)

{

System.out.println("Exception:"+e);

}

}

/* 获取请求类型是否为“GET” */

boolean getrequest(String s)

{  

if (s.length()>0)

{

if (s.substring(0,3).equalsIgnoreCase("GET")) return true;

}

return false;

}

/* 获取要访问的文件名 */

String getfilename(String s)

{

String f=s.substring(s.indexOf(' ')+1);

f=f.substring(0,f.indexOf(' '));

try

{

if (f.charAt(0)=='/')

f=f.substring(1);

}

catch (StringIndexOutOfBoundsException e)

{

System.out.println("Exception:"+e);

}

if (f.equals("")) f="index.html";

return f;

}

/*把指定文件发送给Web浏览器 */

void sendfile(PrintStream outs,File file)

{

try

{

DataInputStream in=new DataInputStream(new FileInputStream(file));

int len=(int)file.length();

byte buf[]=new byte[len];

in.readFully(buf);

outs.write(buf,0,len);

/*

  DataOutputStream ou=new DataOutputStream(System.out);

  ou.write(buf,0,len);

 */

outs.flush();

in.close();

}

catch (Exception e)

{

System.out.println("Error retrieving file.");

System.exit(1);

}

}

}


测试访问路径:http://localhost:8080/上下文名(一般用工程名)/index.html  另这时run(){ 中没有加while(true)  } 所以此例中只能请求一次,服务器就停止;  


猜你喜欢

转载自blog.csdn.net/weixin_39214481/article/details/80018250
今日推荐