用HTTP协议仿照Tomcat

这个是老师上课讲的,讲完之后感觉很神奇,后来我仔细看了TCP/IP我才发现其实Socket和Tcp/ip差不多,是自己没搞懂。  这科还挂了。。。真心很好,我有机会再学习一下。 


先在项目下新建一个文件夹webapp,仿照tomcat

在这个文件夹下放俩个静态网站项目。随便


public class YcTomcat {
		public static void main(String[] args) throws IOException {
			ServerSocket ss = new ServerSocket(9000); 
			while (true) {
				Socket s = ss.accept();
				System.out.println("一个socket对象进来了");
				Thread t = new Thread(new TomcatService(s));
				t.start();
			}
		}
	}
	/*
	在浏览器中输入地址,然后浏览器给你拼接好一段基于http协议的数据包,然后通过DNS发送到主机。
	服务器通过数据包中数据找到指定的文件,并返回流给客户端
	*/



public class TomcatService implements Runnable {
	private Socket s;
	private InputStream iis;  //输入流
	private OutputStream oos; //输出流 
	private Scanner in;       //输入
	private PrintWriter out;  //输出
	
	/**
	 * 在构造方法中把流什么的先定义好
	 * @param s
	 */
	public TomcatService(Socket s){
		try {
			this.iis=s.getInputStream();
			this.oos=s.getOutputStream();
			in=new Scanner(iis);
			out=new PrintWriter(oos);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public void run() {
		//从输入流中读取协议的请求头,解析出请求的资源的地址   => Request对象   
		YcRequest request=new YcRequest(in);
		String address=request.parse();
		//根据这个地址以流的方式读取这个文件   
		String htmlContent=readHtmlFile(address); 
		
		//将这个文件的内容以输出流的形式传给客户端     => Response对象    
		YcResponse response=new YcResponse(out);
		response.writeToClient(htmlContent);  
	}
	
	/**
	 * 通过地址来获取一个html文件字符串代码
	 * @param address
	 * @return
	 */
	private String readHtmlFile(String address) {
		StringBuffer htmlContent=new StringBuffer("");
		String projectPath=getClass().getResource("/").getFile().toString();
		//     /C:/Users/suibian/workspace/YCTomcat/bin/
		projectPath=projectPath.substring(0, projectPath.lastIndexOf("/bin/"));
		System.out.println("项目的位置 :"+projectPath); 
		//  address=/cn/in.html
		File f=new File(projectPath,"/webapp/"+address);
		BufferedReader reader=null;
		try {
			reader =new BufferedReader(new FileReader(f));
			char[] buffer=new char[1024];
			int length=-1;
			while((length=reader.read(buffer,0,buffer.length))!=-1){
				String t=new String(buffer);
				htmlContent.append(t);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();	
			htmlContent.append("<h1>404</h1>");
		}catch(IOException e){
			e.printStackTrace();
			htmlContent.append("<h1>500</h1>");
		}finally{
			try {
				reader.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return htmlContent.toString();
	}
}


public class YcRequest {
	private Scanner sc;
	
	public YcRequest(Scanner sc){
		this.sc=sc;
	}
	public String parse(){
		StringBuffer address=new StringBuffer("");
		//1.从scanner中读取数据,字符串 
		//2.从字符串中取出资源地址部分
		//3.返回这个地址
		if(sc.hasNext()){
			address.append(sc.nextLine());
		}
		/*  浏览器输入http://localhost:9000/cn/in.html,然后浏览器封装了HTTP数据包
		 *  经过DNS解析,然后发送给主机localhost,建立一个socket双向连接
		 *  GET /cn/in.html HTTP/1.1
		 */
		System.out.println("客户端传过来的http协议为:"+address);
		String[] strs=address.toString().split(" ");
		return strs[1];
	}
}



public class YcResponse {
	private PrintWriter out;
	
	public YcResponse(PrintWriter out){
		this.out=out;
	}
	public void writeToClient(String htmlContent){
		/* 拼接好HTTP返回数据包,原来那个ajax那个200之后回送的数据包是这样拼接的 */
		out.println(  "HTTP/1.1 200 OK\r\nContent-Type: text/html;charset=utf-8\r\nContent-Length: "+htmlContent.getBytes().length+"\r\n\r\n"  );
		out.println(htmlContent);
		out.flush();
		out.close();
	}
}


再来一个浏览器来解释数据的封装 

public class Browser {
	 
	public static void main(String[] args) throws UnknownHostException, IOException {
		 Scanner sc=new Scanner(System.in);
		 String path=sc.nextLine();
		 
		 URL url=new URL(path);
		 if("http".equals(url.getProtocol())){ //有许多协议,ftp,http,smtp等等
			 Socket s=new Socket(url.getHost(),url.getPort()); 
			 InputStream iis=s.getInputStream();
			 OutputStream oos=s.getOutputStream();
			 
			 String protocal="GET "+url.getPath()+" HTTP/1.1\r\n";  //拼接的时候一定要注意
			 oos.write(protocal.getBytes());
			 oos.flush();
			 
			 StringBuffer sb=new StringBuffer("");
			 byte[] buffer=new byte[1024];
			 int len=-1;
			 while(   (len=iis.read(buffer, 0, buffer.length))!=-1 ){
				 String ss=new String(buffer,0,len);
				 sb.append(ss);
			 }
			 System.out.println(sb);
			 s.close();
		 }
	}
}


下一篇讲一下有关于http协议。  

我是菜鸟,我在路上。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值