1.如何启动?
main方法是程序的入口,tomcat也不例外,查看tomcat源码,发现main是在Bootstrap 类中的;
2.如何建立连接?
要通讯,必须要建议socket连接,我们需要使用哪种socket,是根据它使用的哪种协议进行判断的。tcp协议or udp协议?http协议本身属于tcp协议,因此我们选择的socket是基本tcp协议的socket。在tomcat中,StandardServer 中 await() 方法具体实现了 socket连接;
3.使用哪种io模式?
代码示例:
public class Server { public static void main(String[] args) throws IOException { new Server().start(); } public void start() throws IOException { ServerSocket serverSocket = new ServerSocket(8888); Socket socket = null; System.out.println("启动web服务"); while (true) { socket = serverSocket.accept(); Thread thread = new Thread(new HttpServerThread(socket)); thread.start(); } } // 内部类 private class HttpServerThread implements Runnable { Socket socket = null; HttpServerThread(Socket socket) { this.socket = socket; } @Override public void run() { InputStream is = null; OutputStream os = null; BufferedReader br = null; try { is = this.socket.getInputStream(); os = this.socket.getOutputStream(); // 页面的请求 br = new BufferedReader(new InputStreamReader(is)); String line = br.readLine(); int i = 0; while (null != line && br.ready()) { line = br.readLine(); System.out.println("第" + i + "行信息:" + line); i++; } // 页面的响应 String reply = "HTTP/1.1\n"; // 必须添加的响应头 reply += "Content-type:text/html\n\n"; // 必须添加的响应头 reply += "服务器返回的消息"; os.write(reply.getBytes()); } catch (IOException e) { e.printStackTrace(); } finally { try { os.close(); is.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
在浏览器上输入:http://localhost:8888/
控制台输出:
第0行信息:Host: localhost:8888 第1行信息:Connection: keep-alive 第2行信息:Cache-Control: max-age=0 第3行信息:User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 第4行信息:Upgrade-Insecure-Requests: 1 第6行信息:Accept-Encoding: gzip, deflate, br 第5行信息:Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 第8行信息:Cookie: JSESSIONID=F373E4FD1D4E6E57AB618563B796B909; 第7行信息:Accept-Language: zh-CN,zh;q=0.9 第9行信息:
控制台上的输出包含http请求头信息,socket接收的流格式为字符类型,每一行都代表一种类型的信息,因此解析时需要逐行解析。之前使用BufferedReader的readLine( )方法,但是此方法是阻塞线程的,如果读取不到,会一直处理等待状态,因此配合ready( )方法一起使用。
原文:https://www.cnblogs.com/caoxb/p/9326733.html