tomcat 的原理

Servlet 是在服务器上运行的小程序,是Web服务端封装的组件。

没有servlet时是怎样的:

在CS 通讯中,客户端socket 与服务端serversocket 建立通信,serversocket监听接受连接,启动一接收线程IOThread,IOThread读写SOCKET,输出每行的数据,分析每行数据,得到请求方法;这里的serversocket 就是一个servlet 的底层;servlet 对serversocket 封装; 其中把场景切到BS 结构,此时如何启动服务器是一个问题,在cs中有main方法可以启动;所以在java中提供applet小应用程序可以在web中运行java类;所以servlet = service + applet;然而,在服务器上运行Java,这种程序可使用 Java 编程语言实现。在通信量大的服务器上,JavaServlet 的优点在于它们的执行速度更快于 CGI 程序。各个用户请求被激活成单个程序中的一个线程,而无需创建单独的进程,这意味着服务器端处理请求的系统开销将明显降低.

几点优势:

1.Servlet 在 Web 服务器的地址空间内执行。这样它就没有必要再创建一个单独的进程来处理每个客户端请。

2.Servlet 是独立于平台的,因为它们是用 Java 编写的。

3.Java 类库的全部功能对 Servlet 来说都是可用的。它可以通过 sockets 和 RMI 机制与 applets、数据库进行交互。


作用:

1.读取客户端(浏览器)发送的数据如(表单、cookie,媒体类型等浏览器能解析的)

2.处理数据并生成结果

3.发送数据到客户端(浏览器),数据格式可以有很多(html,xml,gif,excel等)


这个问题,可以参考“为什么使用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)  } 所以此例中只能请求一次,服务器就停止;  


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值