标签:null 硬件 请求 http请求 tp服务器 tostring system stack .so
诸如tomcat等web服务器中间件简化了我们web的开发成本,但有时候我们或许并不需要这么一个完备的服务器,只是希望做一个简单地处理或者做特殊用途的服务器。
本文将提供一个HTTP的服务器示例,采用Java的ServerSocket进行编码。随着计算机硬件的提升,以及Java地不断优化,使用Java网络编程实现web服务器在实际性能上已经开始可以跟C进行竞争。
以下代码分为两块:
1)HttpServer:主要包含一个ServerSocket,用于接收客户端请求。并通过线程池将请求从主线程剥离,分散到各个线程中去处理;
2)RequestHandler:实现了Runnable接口,将获取一个线程来处理各个请求;流的读取和响应遵循HTTP协议。
注意:编写Http服务器和一般的socket程序并没有太大不同,但是你需要遵循HTTP协议,这样对于采用HTTP协议的客户端或者其它服务器就可以直接进行HTTP请求来通讯。
import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.*; /** * Http服务器端示例,端口设置为8080,编码设置为UTF-8 * @author lay * @date 2019-01-01 */ public class HttpServer { private static final int port = 8080; /** * 启动HTTP服务器 */ public void start() throws IOException { // 初始化线程池 ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>()); // 初始化服务器socket ServerSocket serverSocket = new ServerSocket(port); System.out.println("ServerSocket启动完成"); while (true) { // 阻塞等待socket连接 System.out.println("等待socket"); Socket socket = serverSocket.accept(); // 提交至线程池处理 executor.submit(new RequestHandler(socket)); System.out.println("提交线程池处理请求"); } } public static void main(String[] args) { try { new HttpServer().start(); } catch (IOException e) { throw new RuntimeException(e); } } }
import java.io.*; import java.net.Socket; /** * 请求处理类 * @author lay * @date 2019-01-01 */ public class RequestHandler implements Runnable { /** * HTTP响应头 */ private static final String response = "http/1.1 200 ok"; private static final String splitStr = "\r\n"; private Socket socket; private BufferedReader reader; private BufferedWriter writer; public RequestHandler(Socket socket) throws IOException { this.socket = socket; this.reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); this.writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); } /** * 响应结果 * @param content 响应内容 * @throws IOException IO异常抛出 */ public void sendResponse(String content) throws IOException { writer.write(String.format("%s%s", response, splitStr)); writer.write(splitStr); writer.write(content); } /** * 获得请求 * @return 请求文本 * @throws IOException IO异常抛出 */ public String getRequest() throws IOException { StringBuilder stringBuilder = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { stringBuilder.append(line); stringBuilder.append(splitStr); // 空字符串 if (line.isEmpty()) { break; } } System.out.println("request:\r\n" + stringBuilder); return stringBuilder.toString(); } @Override public void run() { try { String request = getRequest(); // 这里直接把请求数据响应回去 sendResponse(request); writer.flush(); } catch (IOException e) { e.printStackTrace(); } finally { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } try { writer.close(); } catch (IOException e) { e.printStackTrace(); } try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
请求处理器这里直接将请求的HTTP内容返回回去了,如果你使用浏览器请求8080端口,你会看到如下内容:
不过浏览器会默认请求一个icon,所以针对一个URL地址会有两个请求
你可以在ico请求的时候返回一个二进制的ico文件流,它将显示在浏览器的tab上。
扩展点:
1)我们可以像tomcat一样去支持Java Servlet API
2)支持如GET、POST、PUT、DELETE等restful请求
3)将程序配置进行XML配置
4)增加管理界面
5)请求跟踪处理
6)缓存、非阻塞IO、通道来增加性能
标签:null 硬件 请求 http请求 tp服务器 tostring system stack .so
原文地址:https://www.cnblogs.com/lay2017/p/10206505.html