Tomcat是怎么炼成的?(1)兼一点废话

     其实想做这事儿的想法大概去年就形成了,最初是想去翻译《How Tomcat works》这本书,大概翻译到一半左右的时候,因为种种原因停止了,这确实是一本很好的书,可惜最终没有能坚持下来,不过上周看到了这本书的中文版已经上市了,浏览了一下,翻译的质量还不错,当然比我的肯定好多了,可惜这究竟这本书成书比较早,而且怎么说呢?总感觉离我这种小菜鸟比较远的感觉,所以才再准备写这一系列教程吧算是。总结来说是想分为两个目的:
1 每次都能写出个可以用的东西,这里代码可能不漂亮,可以不健壮,但一定可以用,在这个基础上,我们再对代码精雕细琢,我们是针对小菜鸟的,我也更欢迎高手来指正;
2 前面提到了这本书成书比较早,所以Tomcat6以及之后的版本就没有涉及,这里也希望可以从Tomcat的演进版本中学习一点,按照我目前的计划来看,这部分估计会以外传(话说我还是挺喜欢看网络小说的)的形式出现。
     其实这个系列教程我已经写了一点,总想多写一点再发上来,不给自己太大的压力,不过之前在CSDN上也看到了类似的文章(http://blog.csdn.net/beijiguangyong/article/details/7439352) ,总觉得不能让自己太放松,我总有太多想做的事情,总得开始吧!。好了,废话说完了~
       再强调一下,我希望能够一次一点的,每次保证一个可以运行的程序为结束,最终能够将简易版的Tomcat写出来。我坚信,前途是光明的,但道路是曲折的。需要你的不多,一台Java环境配置好的电脑,一个eclipse,自认为懂点Java,有个想搞点事儿的心,可以了,开始吧!

一、 看看HTTP协议
       我们要写的Tomcat是一个WEB服务器,那WEB服务器该如何工作?HTTP协议又具体是怎么回事?这里我们举个例子来说:
       在飞机场都会设置一个服务台,当我们告诉服务台的工作人员我们需要乘坐的航班号之后,服务人员就会告诉我们需要在哪个柜台进行办理手续。而对应来说,当我们在浏览器的地址栏输入一个网址之后,点击回车,想去访问这个网站时,这就相当于我们问这个网站的服务器我们要访问这个网站。这时网站服务器会根据我们的网址,找到我们需要的那个页面,返回给我们的浏览器。浏览器就能把这些内容展示到页面上。而我们在机场和服务台的工作人员沟通是用的我们的语言,而浏览器和服务器沟通也有他们的语言,他们的语言比较简单,都是一个固定的格式,称为协议,而为什么叫HTTP协议呢?与HTML语言又有什么关系?这些我们在后面涉及到的时候也会提到,当然如果你现在Google一下就更好了。说了这么多,我们现在就要看看这个HTTP协议是个什么样子?我们来写个最简单的服务器来看看吧!

package com.tomcat;

import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

public class Main {
	
	public static void main(String[] args) throws UnknownHostException, IOException{
		System.out.println("Server started!");
		// 创建一个ServerSocket对象,监听本机8080端口
		ServerSocket serverSocket = new ServerSocket(8080, 0, InetAddress.getByName("127.0.0.1"));
		while(true){
			// 当有在8080端口访问的时候,调用accept方法得到Socket对象
			Socket socket = serverSocket.accept();
			// 通过Socket获得InputStream流,经过解析得到浏览器发过来的字符串
			InputStream inputStream = socket.getInputStream();
			StringBuilder stringBuilder = new StringBuilder();
			byte[] bytes = new byte[2048];
			int bytesLength = inputStream.read(bytes);
			for(int i =0 ; i<bytesLength; i++){
				stringBuilder.append((char)bytes[i]);
			}
			System.out.println("----the resques string----");
			System.out.print(stringBuilder.toString());
			System.out.println("--------------------------");
		}
	}
}

      我们的服务器是基于Java开发的,因此我们还真算是站在了巨人的肩膀之上,这些在后面的开发中我想会体会的更多。        这里我们主要使用的 Java类包括:ServerSocket类、Socket类以及IO包中的InputStream类。下面我简单解释一下这段程序:
      首先我们使用ServerSocket的构造方法,在本机上监听8080端口,创建一个ServerSocket对象。用于接受所有访问本机8080端口的“信息”。下面用了一个死循环,让这个程序一直运行。
      在这个循环体中,ServerSocket的accpet方法很重要,当有一个程序访问到机器的8080端口时,accept方法会将这个访问信息转化为Socket对象。我们就可以通过这个Socket对象知道访问我们服务器的程序到底是要做什么事情了。
      那如何通过 Socket对象知道呢?这里是通过取得Socket对象的成员变量InputStream对象。熟悉Java IO包的朋友应该对这个类肯定不陌生。后面就是调用InputStream对象的read方法,将程序请求的信息读到一个byte数组中。这里你可能会有一个疑问,为什么这个byte数组是2048这么大?万一请求的信息多了怎么办?那会不会有信息丢失呢?好问题,这个将会在具体解释HTTP协议的时候就好理解。
      好,后面我们还需要把byte数组的信息转换为String,这个对你来说应该是小菜一碟了,最后,我们把这个请求信息输出来吧,到底要看看这个HTTP协议是个什么样子?
     怎么样,这个只有三十几行的代码还不算难懂吧,但不要小看它,可以这么说,几乎所有的网络服务器的原型都和它差不多呢。
      这个程序该怎么测试呢?这个简单,首先将我们刚刚完成的程序运行起来,然后打开你电脑里任意一个浏览器,在地址栏里输入:http://localhost:8080/index.html 点击回车后,接着不需要理浏览器上的内容,我们回过头来看Eclipse里的控制台打出的内容吧: 
GET /index.html HTTP/1.1
Host: localhost:8080
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

       这里根据你使用不同的浏览器,可能上面打出的结果一定的差别,这里我们暂且不作讨论。上面这一系列内容其实就是浏览器向服务器申请访问页面时的请求,这个请求的语法就是HTTP协议,后面我们也还会多次提到这段代码,现在我们先来谈谈第一行。
GET /index.html HTTP/1.1
       第一个单词GET,我想了解网页编程的朋友一定不会陌生,一般来说,数据提交的方式主要就有GET和POST两种方式,这里是告诉我们以GET方式,其中的异同这里不再赘述。

       第二个是一个文件路径,这里我们看一下我们希望访问的路径: http://localhost:8080/index.html ,其实我们就是想访问这个根目录下叫做index.html的文件。这里我们从这句话中就可以知道。

       第三个 HTTP/1.1协议,是告诉我们服务器,传输内容是遵守HTTP/1.1协议的规范,这里关于1.0和1.1协议的异同可以去找Google大神,这里就不再多解释。

       好,通过上面的分析,我们了解到可以根据读取的浏览器请求内容,得到需要访问的文件路径,那我们该如何把这个内容返回给浏览器呢?请关注下一部分内容:一个最简单的Web服务器。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值