最简单的http服务器试水

编程入门 行业动态 更新时间:2024-10-23 09:35:51

<a href=https://www.elefans.com/category/jswz/34/1769011.html style=最简单的http服务器试水"/>

最简单的http服务器试水

最简单的http服务器试水

添加了多线程的部分,处理无效请求的部分。

package com.myhttpserver;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.ServerSocket;
import java.Socket;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;/*** 简易版Http服务器*/public class HttpServer {private static class MyRuntimeException extends RuntimeException{// 在这里实现它的构造方法, override methodpublic MyRuntimeException() {super();}public MyRuntimeException(String message) {super(message);}public MyRuntimeException(String message, Throwable cause) {super(message, cause);}public MyRuntimeException(Throwable cause) {super(cause);}protected MyRuntimeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}}// 创建HttpServer,先来一个构造方法,构造方法里传一个port进来/*** 构造方法* @param port 监听的端口*/public HttpServer(int port) throws IOException, InterruptedException {if(port < 1 || port > 65535){// 端口是 1 - 65535,如果不是,抛出一个自定义的异常throw new MyRuntimeException("端口错误,端口必须在1到65535之间");}// 如果是好的,服务器端要监听一个端口,就是传入的port端口,提供tcp服务。/*** Java中能接收其他通信实体连接请求的类是 ServerSocket,ServerSocket监听来自* 客户端的Socket连接,如果没有连接,它将一直处于等待状态* ServerSocket包含一个监听来自客户端连接请求的方法。* Socket accpet(): 如果接收到一个客户端Socket的连接请求,该方法将返回一个与* 客户端对应的Socket。如果没有客户端连接上来,该方法将一直处于等待状态,线程也被阻塞。*/ServerSocket serverSocket = new ServerSocket(port);// 构造具有 50 个线程的线程池ExecutorService pool = Executors.newFixedThreadPool(50);System.out.println("Http服务器已经启动了,开始监听端口:" + port);// 这里需要抛出 IO Exception// 监听了端口之后,需要接收客户端上来的请求while(true){Socket clientSocket = serverSocket.accept();// 接收了客户端的请求System.out.println("接收到来自于客户端的请求");//因为存在浏览器多次请求的问题,我们先来判断一下接收到的客户端Socket是否可用if(clientSocket != null && !clientSocket.isClosed()){// 会产生什么样的问题? 假设我们有 10 个用户来访问,某一个特别耗时// 一种思路/*** 我们在实际开发中,应该使用的都是线程池,我们不能够自己去创建线程* 因为我们创建一个线程,实际上是向操作系统的底层去申请资源,* 非常耗时。* 线程池如何来用?* 线程池构建好之后,怎么来提交我们的任务? 提交任务只能用 runnable的方式*///                (new Thread() {
//                    @Override
//                    public void run() {
//                        try {
//                            acceptToClient(clientSocket);
//                            // 来一个 run 方法,run方法里调用它
//                        } catch (IOException e){
//                            e.printStackTrace();
//                        }catch (InterruptedException e){
//                            e.printStackTrace();
//                        }
//                    }
//                }).start();// 构建好 RunnableRunnable r = () -> {try{acceptToClient(clientSocket);} catch(IOException e){e.printStackTrace();} catch (InterruptedException e){e.printStackTrace();}};pool.submit(r);// 提交之后,从线程池里拿一个线程来运行这个任务}}}/*** 响应数据给客户端的具体方法* 一个线程来处理请求,如果我们处理具体的业务逻辑比较耗时,那么如果有下一个人* 也在请求我们的网页,就会等待。* 因为 acceptToClient(clientSocket) 没有执行完,所以 Socket clientSocket =* serverSocket.accept() 上一个还没运行完,则无法接收到下一次的请求。* 用多线程来解决问题* @param clientSocket* @throws IOException*/private void acceptToClient(Socket clientSocket) throws IOException, InterruptedException{// System.out.println("我收到了客户端请求");// 可以试着获取输入流有多少个字节InputStream clientIn = clientSocket.getInputStream();OutputStream clientOut = clientSocket.getOutputStream();/*** 去掉了 Thread.sleep,只打开一个localhost:12345,显示* 打印了三个"我收到了客户端请求"* 打印输入请求的长度,处理无效请求*/if(clientIn.available() == 0){clientOut.write("HTTP/1.1 200 ok\r\n".getBytes());clientOut.write("Server: myServer/1.0\r\n".getBytes());clientOut.write(("Date: " + (new Date()).toString() + "\r\n").getBytes());clientOut.write("Content-Type: text/html; charset = UTF-8\r\n".getBytes());// 自己的响应格式的响应头部// 响应 html 内容,先返回一个非常简单的htmlclientOut.write("\r\n".getBytes());clientOut.write("<h1>OK!</h1>".getBytes());// 响应完之后,输出流要关闭// 先强制性的把内容刷给客户端clientOut.flush();clientOut.close();return;}//Thread.sleep(10000);// 有一个特别耗时,睡了 10 s// 假设要获取test1.html(输出内容)到客户端的输出流// 输出流就是 clientOut// 把第一行的内容输出出去System.out.println("我收到了客户端请求,浏览器发送上来的请求的数据长度是: " + clientIn.available());clientOut.write("HTTP/1.1 200 ok\r\n".getBytes());clientOut.write("Server: myServer/1.0\r\n".getBytes());clientOut.write(("Date: " + (new Date()).toString() + "\r\n").getBytes());clientOut.write("Content-Type: text/html; charset = UTF-8\r\n".getBytes());// 自己的响应格式的响应头部// 响应 html 内容,先返回一个非常简单的htmlclientOut.write("\r\n".getBytes());clientOut.write("<h1>piao piao first page</h1>".getBytes());// 响应完之后,输出流要关闭// 先强制性的把内容刷给客户端clientOut.flush();clientOut.close();}public static void main(String[] args) throws IOException,InterruptedException{// 我们的服务器启动之后,需要监听一个端口new HttpServer(12345);}
}

更多推荐

最简单的http服务器试水

本文发布于:2024-02-19 16:51:03,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1764847.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:最简单   试水   服务器   http

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!