Http多线程版本
上一篇文章讲了HTTP是如何通过TCP协议传输到服务器上,以及服务器接收到的报文信息
请参考[HTTP与TCP的关系]
这篇文章主要讲述的多线程处理Http请求,关于多线程的好处我就不再叙述了。由于我们的
请求处理可能非常的耗时,导致服务器无法在规定的时间内出力请求,这样服务器的吞吐量比较低,
为了达到高吞吐量,往往在请求处理时使用多线程技术,不会影响接受请求线程,这样一来即使处理
请求的线程堵塞了也不会影响处理请求的线程,这个也是现在比较流行的Reactor模型。
首先来看看处理请求的线程代码:
/** * 处理HTTP请求的一个类 * @author xin.qiliuhai 1045931706@qq.com * @date 2018/4/29 19:15 */ public class HttpHandler implements Runnable { private Socket socket; public HttpHandler(Socket socket){ this.socket=socket; } @Override public void run() { BufferedReader br=null; BufferedWriter bw=null; try{ br = new BufferedReader(new InputStreamReader(socket.getInputStream())); bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); String s; int contentLength = 0; //4.输出请求体中的内容,并且将Content-Length的值赋值给contentLength,确定post请求体的大小 while ((s = br.readLine()) != null && !s.isEmpty()) { System.out.println(s); if (s.indexOf("Content-Length") != -1) { contentLength = Integer.parseInt(s.substring(s.indexOf("Content-Length") + 16)); } } //5.如果有请求体,通过read方法读取请求体中的内容 if (contentLength != 0) { char[] buf = null; if (contentLength != 0) { buf = new char[contentLength]; br.read(buf, 0, contentLength); System.out.println("The data user posted: " + new String(buf)); } } //6 设置响应体内容 bw.write("HTTP/1.1 200 OK "); bw.write("Content-Type: text/html; charset=UTF-8 "); bw.write("<html> " + "<head> " + " <title>first page</title> " + "</head> " + "<body> " + " <h1>Hello World!" + "</h1> " + "</body> " + "</html> "); //7.冲刷到浏览器 bw.flush(); bw.close(); br.close(); //阻塞十秒钟 相当于在执行请求时堵塞了 Thread.sleep(10000); }catch (Exception ex){ ex.printStackTrace(); } } }
单线程调用
/** * HTTP报文 * @author xin.qiliuhai 1045931706@qq.com * @date 2018/4/29 9:09 */ public class HttpDemo { public static void main(String[] args) throws Exception { ServerSocket ss = null; Socket socket = null; try { //1.创建socket连接 ss = new ServerSocket(8080); //循环等待 while (true) { //2.堵塞,直到有新的连接进来 socket = ss.accept(); //3处理相应的请求,这个方法会堵塞 new HttpHandler(socket).run(); } } catch (IOException e) { e.printStackTrace(); } finally { //关闭资源 ss.close(); } } }