自己实现一个简单的支持并发的Web服务器
2016-03-16 17:31
916 查看
前面我们自己实现了一个线程池,现在我们基于前面编写的线程池(http://blog.csdn.net/canot/article/details/50904001)编写一个支持并发访问的Web服务器来处理一些简单的HTTP请求/响应。
启动该服务器:
SimpleHttpServer在建立起与客户端的连接之后,并不会直接处理客户端的请求,而是把其封装成HttpRequestHandler并交给线程池处理。在线程池中则由Worker处理客户端请求的同时,SimpleHttpServer能够继续完成后续客户端连接的建立,并不会阻塞后续客户端的请求。
在该项目的根目录下建立a.html,并放置图片1.jpg:
在浏览器中输入http://localhost:8080/a.html可以看到图片正常显示,则完成了处理html和jpg的HTTP请求。
public class SimpleHttpServer { //定义处理HttpRequest的线程池 static ThreadPool<HttpRequestHandler> threadPool = new DefaultThreadPool<HttpRequestHandler>(); static ServerSocket serverSocket; //该Web服务器的路径 static String basePath; //默认的端口号 static int port = 8080; //启动服务器 public static void start() throws IOException { serverSocket = new ServerSocket(port); Socket client = null; //获取客户端的连接 while ((client = serverSocket.accept()) != null) { //生成一个job放入线程池执行 threadPool.execute(new HttpRequestHandler(client)); } serverSocket.close(); } static class HttpRequestHandler implements Runnable { private Socket client; public HttpRequestHandler(Socket client) { this.client = client; } public void run() { byte[] buff = new byte[1024]; BufferedReader br = null; PrintWriter pw = null; File directory = new File(""); String basePath = directory.getAbsolutePath(); int length = 0; try { //读取客户端发送的请求数据 br = new BufferedReader(new InputStreamReader(client.getInputStream())); //获取请求行的第一行再解析出要请求的资源 String header = br.readLine(); String filePath = header.split(" ")[1]; //判断请求的资源的为html if(filePath.endsWith("html")){ pw = new PrintWriter(client.getOutputStream()); //构造HTTP响应头信息 pw.println("HTTP/1.1 200 Ok"); pw.println("Server: wangxiServer"); pw.println("Content-Type: text/html;charset=UTF-8"); pw.println(""); //通过io流读取访问的资源,然后输出给客户端 InputStream is = new FileInputStream(new File(basePath,filePath)); while((length=is.read(buff))>0){ pw.println(new String(buff,0,length)); } pw.flush(); //判断请求的资源的为jpg }else if(filePath.endsWith("jpg")){ //获取要访问的图片流,把流的数据全部存在ByteArrayOutputStream中 ByteArrayOutputStream bos = new ByteArrayOutputStream(); InputStream is = new FileInputStream(new File(basePath,filePath)); while((length=is.read(buff))>0){ bos.write(buff, 0, length); } byte[] image = bos.toByteArray(); //构造HTTP响应头,输出给客户端 pw = new PrintWriter(client.getOutputStream()); pw.println("HTTP/1.1 200 Ok"); pw.println("Server: wangxiServer"); pw.println("Content-Type: image/jpeg"); pw.println("Content-Length:"+image.length); pw.println(""); //输出图片流 client.getOutputStream().write(image, 0, image.length); }else{ pw.println("HTTP/1.1 200 Ok"); pw.println("Server: wangxiServer"); pw.println("Content-Type: text/html;charset=UTF-8"); pw.println(""); pw.println("404 No Found"); pw.flush(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
启动该服务器:
public class TestMyService { public static void main(String[] args) { try { SimpleHttpServer.start(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
SimpleHttpServer在建立起与客户端的连接之后,并不会直接处理客户端的请求,而是把其封装成HttpRequestHandler并交给线程池处理。在线程池中则由Worker处理客户端请求的同时,SimpleHttpServer能够继续完成后续客户端连接的建立,并不会阻塞后续客户端的请求。
在该项目的根目录下建立a.html,并放置图片1.jpg:
<html> <head> <title></title> </head> <body> <img src="http://localhost:8080/1.jpg"></img> </body> </html>
在浏览器中输入http://localhost:8080/a.html可以看到图片正常显示,则完成了处理html和jpg的HTTP请求。
相关文章推荐
- xcode警告:Implicitly declaring
- PAT--1113. Integer Set Partition
- BusyBox init及inittab文件详解
- CSS之剪切横幅
- 【Unity02】尝试CardboardDemo打包apk
- github 常用项目记录帖,持续更新...
- iOS开发拓展篇—CoreLocation定位服务
- linq to sql -System.Data.Linq.DataContext不包含采用“0”个参数的构造函数
- [Java语言] [Leetcode] Best Time to Buy and Sell Stock 买卖股票的最佳时机
- 读DL论文心得之Fast RCNN
- ios开发之你真的了解了KVC吗?
- 哈理工oj/hrbust 1790 武林【DP】
- Android开发笔记
- NET(C#)接入Dubbo服务,Zookeeper作为Dubbo服务的注册中心,实现thrift协议访问接口(3)
- 企业微信入局,移动办公又演化成BAT大战?
- BZOJ_P1026 [SCOI2009]windy数(动态规划)
- Android开发之利用谷歌API定位
- 路由器与交换机的区分
- SQL数据库的order by排序失效问题
- Fiddler前端页面调试功能简易入门