Java 从零开始手撸一个 HTTP 服务器

Java编写Web开发框架:从零开始打造一个简易框架! 🏆本文收录于「编程与技术实战」专栏,此专栏涵盖了C/C++编程、人工智能、数据结构、机器学习等技术领域的内容,助你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!! 阅读详情

先想想需要达到怎样的要求:

本来这是一个很小的课程设计作业,老师也是要求能达到简单的socket应答就行了。但是我还是觉得有必要自己手撸一个HTTP服务器,毕竟这样更炫酷。

在开始写之前,我们先想想应该达到一个怎样的效果,我自己罗列了一下:

  1. 能在浏览器访问网页,比如:http://localhost:8000/index.html,这样子能解析自己预先准备的index.html:
  2. 能读取文本信息:比如:http://localhost:8000/17.xml,这样子能直接读取文本显示。
  3. 能处理请求异常:比如:http://localhost:8000/we.html,我们不支持这个地址,就会弹出File not found
  4. 持续接受用户的请求(无论正确/错误)

根据我自己对于HTTP服务器的理解,设计出HTTP服务器的生命周期如下:

  • Step1-read:读取socket数据流
  • Step2-parser:解析数据流,分析报头,得到客户给予服务器的命令语义
  • Step3-process:处理客户给的命令语义,返回处理结果
  • Step4-response:把处理结果打包,增加报头
  • Step5-write:写入socket数据流

以上的五步,我们完全可以把他作为一个线程独立出来,我希望:每一次客户向服务器发起请求的时候,我们就独立开辟一条线程去处理客户的需求,说白了,用子线程去独立执行以上的过程。

开始撸码

你应该遵循一下函数设计的规范:

我个人的编码规范,对于一个有返回对象的函数,应该需要设计如下:

    public Object functionExample(Object params){
        Object object1 = null;
        Obejct object2 = null;
        try{
            object1 = new Object();
            object2 = new Object();
            //Do something
            return object1;//Here is the return
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            try{
                //Close object1
                //CLose object2
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        return null;
    }

部分代码如果想偷懒偶尔不写close,我们也可以用这个

@SuppressWarnings("resource") // Warnings iggnore

先写服务器的主线程框架:

package csdn_fake_server;

import java.io.*;
import java.util.logging.Logger;
import java.net.*;


public class Server extends Thread{
    int watchPort = 8000;
    Logger log = Logger.getLogger("SERVER-LOG-JT");//Open log

    public Server(){};
    /**
     * Server
     * @param port: The server listen port
     */
    public Server(int port) {
        watchPort = port;
    }

    //Class httpServer{} 这里将会实现我们上面提到的子线程

    @Override
    public void run() {
        super.run();
        try {
            @SuppressWarnings("resource") // Warnings iggnore
            ServerSocket serverSocket = new ServerSocket(watchPort);
            while (true) { // Waitting for clients
                Socket socket = serverSocket.accept();// Thread Join here
                //Child Thread here
                new httpServer(socket).start();// If connected, start a new server thread
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        Server server = new Server();
        server.start();
    }
}

以上是我写出来一个自己脑海里服务器的线程框架,该类里面你应该要配备一个测试的函数main(String[] args)。

我们在启动服务器线程之后,我们将利用ServerSocket 的accept()通过线程拥塞来监听端口的信息,因此,我们一旦收到服务器的套接字信息之后,就可以开启我们的子线程去处理客户的需求了。

接着写服务器子线程框架实现

    class httpServer extends Thread {

        Socket currentSocket = null; //Client Socket
        InputStream inputStream = null;//Use for get header
        OutputStream outputStream = null;//Use for response

        final static int sucessStatus = 200;//HTTP response header status code
        final static int noResourceStatus = 404;//HTTP response header status code

        int resultStatus = 404; //Our response code
        long responseLength = 20; //@Attention!!! Error info length, Important

        public httpServer(Socket socket) {
            try {
                currentSocket = socket; //Get socket bridge
                inputStream = socket.getInputStream(); // Get inputstream
                outputStream = socket.getOutputStream(); // Get outputstream
            } catch (Exception e) {
                log.info("Connection aborted");
            }
        }

        // Read=>parser=>process=>response=>write
        @Override
        public void run() {
            try {
                String rawString = read(); // Get raw header
                String serverCommand = parser(rawString); // Parser the raw header
                String resultString = process(serverCommand); // Process command
                String rawResultString = response(resultString); // Pack the result
                write(rawResultString);// Write in responsed stream
                currentSocket.close();// CLose the client socket
                //End thread
            } catch (Exception e) {
                log.info("Failed connection");
                e.printStackTrace();
            }
        }

        private String read(){//Step 1
            try{
	            //Read Interface
                return null;
            }catch(Exception e){
                log.info("Read faild");
                e.printStackTrace();
            }
            return null;
        }

        /**
         * 
         * @param rawString: raw String from read()
         * @return server command from client
         */
        private String parser(String rawString) { //Step 2
            try{
            	//Parser Interface
                return null;
            }catch(Exception e){
                log.info("Parser faild");
                e.printStackTrace();
            }
            return null;
        }
        
        /**
         * 
         * @param commandString: command string from parser
         * @return
         */
        private String process(String commandString) { //Step 3   
            try{
            	//Process Interface
                return null;
            }catch(Exception e){
                log.info("Process failed");
                e.printStackTrace();
            }finally{
                try{
                    //Close IO
                }catch(Exception e){
                    log.info("Bad IO");
                    e.printStackTrace();
                }
            }
			return null;
        }
        
        private String response(String resultString) { // Step 4
            try{
	            // response Interface
                return null;
            }catch(Exception e){
                log.info("response failed");
                e.printStackTrace();
            }
            return null;
        }

        private void write(String rawResultString) { //Step 5
            try{
            	//Write Interface
                return;
            }catch(Exception e){
                log.info("write faild");
                e.printStackTrace();
            }
        }
    }

好了,至此,我们的子线程的框架机搭建好了,具体的五个函数还没有实现。

  • read
  • parser
  • process
  • response
  • write

我们来好好思考一下每一步需要完成些什么工作。

第一步:读取原始的报文数据

private String read();//Step 1

读取报文之前,我们应该需要知道Http的报文格式,我们尝试打开现在的代码,然后试一下在浏览器向我们这个还没完成的服务器发送请求:http://localhost:8000/

在这里插入图片描述
如果我们在浏览器发出的请求一般都是GET请求了,对报文数据是在下一步,我们不关心客户给我们发来的数据是什么,我们在这个步骤值考虑把我们的数据流读入进服务器就是了。

因为HTTP的报文数据以“\r\n”作为分割,我们可以选择读取完所有的报文之后,再处理,也可以我们简单地读取第一行就行了,我们可以选择用BufferedReader的IO工具来处理,因为以行作为单位这样的话就更加方便了。

我们写出我们的read接口:

        private String read(){//Step 1
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            try{
                String infoRead = bufferedReader.readLine(); // We only get the line1 as: GET /index.html HTTP/1.1
                log.info(infoRead);
                return infoRead;
            }catch(Exception e){
                log.info("Read faild");
                e.printStackTrace();
            }
            return null;
        }

我这里偷懒没有Close IO,为了控制博文的长度,还是希望以后能加上。

第二步:解析报文

因为我们在上一步读取数据的时候偷懒只读一行了,因此,我们处理解析的时候也是一笔带过就是了,用空格分开GET /index.html HTTP/1.1

        /**
         * @param rawString: raw String from read()
         * @return server command from client
         */
        private String parser(String rawString) { //Step 2
            try{
                String[] split = rawString.split(" ");
                if (split.length != 3) { //@example as: GET /index.html HTTP/1.1
                    throw new NullPointerException();
                }
                return split[1]; // Get path
            }catch(Exception e){
                log.info("Parser faild");
                e.printStackTrace();
            }
            return null;
        }

第三步:处理客户语义

通过上面的解析报文,我们已经知道了客户需要请求一个地址了。因此,我们根据可以给出的地址来从后台读取文件:

		/**
         * @param commandString: command string from parser
         * @return
         */
        private String process(String commandString) { //Step 3  
            FileReader fileReader = null;
            BufferedReader bufferedReader = null;   
            try{
                log.info(commandString);//Show request in server panel
                if(commandString.equals("/")){ //Default get resource
                    commandString = "index.html";
                }
                File file = new File("src/simple_webserver_lab/template/"+commandString);
                fileReader = new FileReader(file);
                bufferedReader = new BufferedReader(fileReader);
                StringBuffer stringBuffer = new StringBuffer();
                String line;
                while((line = bufferedReader.readLine())!=null){
                    stringBuffer.append(line+"\r\n");
                }
                resultStatus = 200; //Success
                responseLength = file.length(); // This is must be added for HTPP Header
                String result = stringBuffer.toString();
                return result;
            }catch(Exception e){
                resultStatus = 404;
                log.info("Process failed");
                e.printStackTrace();
            }finally{
                try{
                    bufferedReader.close();
                    fileReader.close();
                }catch(Exception e){
                    resultStatus = 404;
                    log.info("Bad IO");
                    e.printStackTrace();
                }
            }
            return null;
        }

第四步:(巨坑)响应客户返回数据包

HTTP报头的content length是一个大坑

  • 需要两次的\r\n
  • 长度必须匹配!!!!

看这里:

<h1>File not found...</h1>

为毛后面写这些点,就是为了填补上不够数的字节,如果你差一个字节,都会不出来结果的,浏览器会报错的。

我们给出的数据只能比要求的content length要长!

我在前面定义了一个全局的响应长度:

        long responseLength = 20; //@Attention!!! Error info length, Important

像上面如果你返回:<h1>Error</h1>就会空白,因为你的数据不满足http报文的数据长度,因此我们会丢弃掉这个分组的数据了。

还有就是:HTTP/1.1 之间不要空格,否则 Firefox 系列的浏览器检查会出错哦。

响应部分的代码:

        /**
         * @param resultString
         * @return raw response result
         */
        private String response(String resultString) { // Step 4
            try{
                StringBuffer responseInfo = new StringBuffer();
                switch(resultStatus){
                    case sucessStatus:{
                        responseInfo.append("HTTP/1.1 200 ok \r\n");
                        responseInfo.append("Content-Type:text/html \r\n");
                        responseInfo.append("Content-Length:"+Long.toString(responseLength)+" \r\n\r\n");
                        responseInfo.append(resultString);
                        break;
                    }
                    case noResourceStatus:{
                        responseInfo.append("HTTP/1.1 "+Integer.toString(noResourceStatus)+" file Not Found \r\n");
                        responseInfo.append("Content-Type:text/html \r\n");
                        responseInfo.append("Content-Length:"+Long.toString(responseLength)+" \r\n\r\n");
                        responseInfo.append("<h1>File not found...</h1>");
                        break;
                    }default:{
                        break;
                    }
                }
                return responseInfo.toString();
            }catch(Exception e){
                log.info("response failed");
                e.printStackTrace();
            }
            return null;
        }

第五步:写入Socket的数据流

这个就没啥好说的了

        /***
         * @param rawResultString
         */

        private void write(String rawResultString) { //Step 5
            try{
                outputStream.write(rawResultString.getBytes());
                outputStream.flush();
                outputStream.close();
                return;
            }catch(Exception e){
                log.info("write faild");
                e.printStackTrace();
            }
        }

测试结果:

启动服务器:

    public static void main(String[] args) {
        Server server = new Server();
        server.start(); //服务器的主线程启动
    }

前提你要有一个index.html在你的指定目录。

假如我们访问根和指定访问index.html,都会显示:
在这里插入图片描述

在这里插入图片描述
后台打印:
在这里插入图片描述
假如,我们访问目录下的文本文件:17.xml,将会显示文本内容:
在这里插入图片描述
终端:
在这里插入图片描述
假如我们访问一个不存在的路径:
在这里插入图片描述
后台打印:
在这里插入图片描述
至此,我们撸完了一个简易的 Http 服务器了。

完整代码:

项目文件夹:
在这里插入图片描述
Server.java


package simple_webserver_lab;

import java.io.*;
import java.util.logging.Logger;
import java.net.*;

/**
 * @author:JintuZheng
 * @version: 1.0.00
 */

public class Server extends Thread {  


    int watchPort = 8000;
    Logger log = Logger.getLogger("SERVER-LOG-JT");

    public Server(){};
    /**
     * Server
     * @param port: The server listen port
     */
    public Server(int port) {
        watchPort = port;
    }

    /**
     * @apiNote: The child httpServer
     */
    class httpServer extends Thread {

        Socket currentSocket = null; //Client Socket
        InputStream inputStream = null;//Use for get header
        OutputStream outputStream = null;//Use for response

        final static int sucessStatus = 200;//HTTP response header status code
        final static int noResourceStatus = 404;//HTTP response header status code

        int resultStatus = 404; //Our response code
        long responseLength = 20; //@Attention!!! Error info length, Important

        public httpServer(Socket socket) {
            try {
                currentSocket = socket; //Get socket bridge
                //log.info(socket.getInetAddress().toString()); //Show ip address
                inputStream = socket.getInputStream(); // Get inputstream
                outputStream = socket.getOutputStream(); // Get outputstream
            } catch (Exception e) {
                log.info("Connection aborted");
            }
        }

        // Read=>parser=>process=>response=>write
        @Override
        public void run() {
            try {
                String rawString = read(); // Get raw header
                String serverCommand = parser(rawString); // Parser the raw header
                String resultString = process(serverCommand); // Process command
                String rawResultString = response(resultString); // Pack the result
                write(rawResultString);// Write in responsed stream
                currentSocket.close();// CLose the client socket
                //End thread
            } catch (Exception e) {
                log.info("Failed connection");
                e.printStackTrace();
            }
        }

        private String read(){//Step 1
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            try{
                String infoRead = bufferedReader.readLine(); // We only get the line1 as: GET /index.html HTTP/1.1
                log.info(infoRead);
                return infoRead;
            }catch(Exception e){
                log.info("Read faild");
                e.printStackTrace();
            }
            return null;
        }

        /**
         * 
         * @param rawString: raw String from read()
         * @return server command from client
         */
        private String parser(String rawString) { //Step 2
            try{
                String[] split = rawString.split(" ");
                if (split.length != 3) { //@example as: GET /index.html HTTP/1.1
                    return null;
                }
                return split[1]; // Get path
            }catch(Exception e){
                log.info("Parser faild");
                e.printStackTrace();
            }
            return null;
        }
        
        /**
         * 
         * @param commandString: command string from parser
         * @return
         */
        private String process(String commandString) { //Step 3  
            FileReader fileReader = null;
            BufferedReader bufferedReader = null;   
            try{
                log.info(commandString);//Show request in server panel
                if(commandString.equals("/")){ //Default get resource
                    commandString = "index.html";
                }
                File file = new File("src/simple_webserver_lab/template/"+commandString);
                fileReader = new FileReader(file);
                bufferedReader = new BufferedReader(fileReader);
                StringBuffer stringBuffer = new StringBuffer();
                String line;
                while((line = bufferedReader.readLine())!=null){
                    stringBuffer.append(line+"\r\n");
                }
                resultStatus = 200;
                responseLength = file.length(); // This is must be added for HTPP Header
                String result = stringBuffer.toString();
                return result;
            }catch(Exception e){
                resultStatus = 404;
                log.info("Process failed");
                e.printStackTrace();
            }finally{
                try{
                    bufferedReader.close();
                    fileReader.close();
                }catch(Exception e){
                    resultStatus = 404;
                    log.info("Bad IO");
                    e.printStackTrace();
                }
            }
            return null;
        }
        
        /**
         * 
         * @param resultString
         * @return raw response result
         */
        private String response(String resultString) { // Step 4
            try{
                StringBuffer responseInfo = new StringBuffer();
                switch(resultStatus){
                    case sucessStatus:{
                        responseInfo.append("HTTP/1.1 200 ok \r\n");
                        responseInfo.append("Content-Type:text/html \r\n");
                        responseInfo.append("Content-Length:"+Long.toString(responseLength)+" \r\n\r\n");
                        responseInfo.append(resultString);
                        break;
                    }
                    case noResourceStatus:{
                        responseInfo.append("HTTP/1.1 "+Integer.toString(noResourceStatus)+" file Not Found \r\n");
                        responseInfo.append("Content-Type:text/html \r\n");
                        responseInfo.append("Content-Length:"+Long.toString(responseLength)+" \r\n\r\n");
                        responseInfo.append("<h1>File not found...</h1>");
                        break;
                    }default:{
                        break;
                    }
                }
                return responseInfo.toString();
            }catch(Exception e){
                log.info("response failed");
                e.printStackTrace();
            }
            return null;
        }
        /***
         * 
         * @param rawResultString
         */

        private void write(String rawResultString) { //Step 5
            try{
                outputStream.write(rawResultString.getBytes());
                outputStream.flush();
                outputStream.close();
                return;
            }catch(Exception e){
                log.info("write faild");
                e.printStackTrace();
            }
        }
    }

    @Override
    public void run() {
        super.run();
        try {
            @SuppressWarnings("resource") // Warnings iggnore
            ServerSocket serverSocket = new ServerSocket(watchPort);
            while (true) { // Waitting for clients
                Socket socket = serverSocket.accept();// Thread Join here
                new httpServer(socket).start();// If connected, start a new server thread
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Server server = new Server();
        server.start();
    }
}

从零开始学写HTTP服务器(三)请求资源 客户端通过URI,Content-Type等请求头的内容访问服务端的特定实体,今天主要学习这部分内容。(一)C++文件I/O服务端收到HTTP请求后,需要对请求头进行解析,之后获取响应资源,最后返回。 本文使用C++ file stream的方式读取文件后返回。C++ file stream提供3个接口: 1.ofstream: Stream class to write on files 阅读详情

相关推荐

Java手写HTTP服务器:协议解析与HTML响应

超文本传输协议(HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议。它是互联网上应用最为广泛的一种网络协议,所有的WWW文件都必须遵守这个标准。HTTP是一个客户端和服务器端请求和应答的标准。通过使用Web浏览器、网络爬虫或者其它的工具,客户端发起一个请求到服务器上,请求获取一个数据资源。Java网络API为开发网络应用程序提供了丰富、灵活的接口。从Java 1.0版本开始,Java便内置了网络编程能力,经历了多个版本的演进,这些API已经非常成熟和稳定。

weixin_42513870的博客 968

用Java Socket手撸了一个HTTP服务器

这一块需要注意一点,正文可能为空,也可能有数据;有数据时,我们要如何把所有的数据都取出来呢?

恒二哥的博客 2035

手把手教你用QEMU虚拟化华为路由器固件(附完整网络配置指南)

本文提供了一份详尽的QEMU虚拟化华为路由器固件的实战指南。从固件解包、网络桥接配置到QEMU虚拟机启动,手把手教你搭建完整的嵌入式设备沙箱环境,特别适合安全研究、逆向分析和学习嵌入式系统工作原理。

tgb3456789的博客 937

使用java自制简易web服务器

记得好多年前,刚刚开始学javaweb的时候,老师教的第一件事是安装jdk,第二件事就是安装tomcat了。当时老师的操作是,下载完压缩包后解压,然后把tomcat的bin目录添加到环境变量里面,然后打开黑乎乎的cmd,输入catalina就可以运行tomcat了。当时还不知道为什么只要添加了环境变量,就可以在cmd里面启动tomcat,更不要说为什么我们什么都没有设置,输入一个命令就能启动web服务器了。

haohulala的博客 2233

RSA 2048/4096 签名校验算法

RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。 RSA是目前最有影响力和最常用的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。 今天只有短的RSA钥匙才可能被强力方式解破。到2008年为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能...

qq_38769551的博客 9491

IT运维必备 开源Urbackup 备份系统部署教程 实战操作

手动添加ip方式检查是否在线 ,linux需要按上述步骤6配置server端地址 不然一直不会进去状态栏。安装依赖sudo apt install -y libcrypto++-dev。补充客户端手动触发备份命令 (一般在服务端操作即可,特殊情况客户端进行操作)修改ubuntu主机名 建议修改为ip 方便上线以ip命名上线。默认客户端安装完毕大概几分钟之内服务端会自动上线。配置客户端指向server端地址。(2)ubuntu 客户端设置。新起一个远程窗口查看配置状态,配置客户端备份文件目录。

qq_34981755的博客 1278

自己动手——快速搭建Java应用服务器

Motivation 我写这套帖子的目的,是在自己学会、实现并熟练掌握之后,想帮助下面将会提到的这样一群正在学习Android的新手(虽然我自己也是新手),通过自己的经验传递出去,让他们少走一点弯路,节省大量用在查询和翻阅资料的时间。 我在学习编写自己的Android应用程序服务器的时候遇到过以下的问题: 1.我需要准备什么? 2.我该选择哪一套实现方案? …… 这些问题的搜索和查证都...

石沉溪洞 7万+

爬虫风控实战:当你的代理IP被数美滑块盯上时,如何优雅破解?

本文深入探讨了爬虫风控对抗中数美滑块验证码的破解与防御策略。通过分析数美滑块的多层防御机制,提出了代理IP池精细化管理、请求特征拟人化改造以及工程化滑块验证解决方案等系统性方法,帮助开发者有效降低验证码触发率,提升爬虫效率。

weixin_27419879的博客 206

快速搭建一个自己的服务器详解(java环境)

一. 服务器的购买 1. 我选择的是阿里云的服务器,学生价9.5元一个月,百度直接搜索阿里云,然后点击右上角登录,推荐大家用支付宝扫码登录,方便快捷。阿里云官网的东西比较多,登录后我找了很久也没有找到学生服务器在哪里卖,最后在咨询里找到了这个网址,https://promotion.aliyun.com/ntms/campus2017.html,购买的时候需要进行学生认证,按照他的要求一步步...

GuoZebin的博客 17万+

告别迷茫!用ETAS RTA-OS配置你的第一个AUTOSAR OS任务(含VRTA虚拟ECU实战)

本文详细介绍了如何使用ETAS RTA-OS工具链在VRTA虚拟ECU上配置和运行第一个AUTOSAR OS任务。通过从XML配置到任务调度的全流程实战,帮助开发者快速掌握嵌入式操作系统开发的核心步骤,特别适合刚接触AUTOSAR的开发者快速上手。

weixin_42533622的博客 418

ENSP之配置静态路由

ENSP之配置静态路由 两台路由器两台PC 拓扑图如下: 配置AR1线路上的两条IP地址 配置AR2线路上的两条IP地址 3.AR2上 配置静态IP 路由 AR1上 配置静态IP 路由 设置两台PC 的IP地址 网关 PC1 PC2 全部配置好了之后 现在测试PC1是否ping 得通PC2 在命令行输入 成功的话如下图 ...

浪友与泪的博客 3544

使用Java Socket手撸一个http服务器

原文连接:使用Java Socket手撸一个http服务器 作为一个java后端,提供http服务可以说是基本技能之一了,但是你真的了解http协议么?你知道知道如何手撸一个http服务器么?tomcat的底层是怎么支持http服务的呢?大名鼎鼎的Servlet又是什么东西呢,该怎么使用呢? 在初学java时,socket编程是逃不掉的一章;虽然在实际业务项目中,使用这个的可能性基本为0,本篇...

weixin_34006468的博客 391

Abaqus梁模型仿真中的常见陷阱与优化策略

本文深入探讨了Abaqus梁模型仿真中的常见陷阱与优化策略,涵盖几何建模、材料属性设置、边界条件处理等关键环节。针对梁截面方向定义、网格划分、复合截面建模等典型问题,提供了实用的Python脚本示例和优化方案,帮助工程师避免计算错误并提升仿真精度。文章特别强调了动力分析中的网格密度要求和材料非线性考虑,为复杂工程应用提供专业指导。

weixin_29099217的博客 459

从零开始用Java实现一个简单的Web服务器

## 从零开始用Java实现一个简单的Web服务器#### 1. 创建项目结构首先新建一个Java项目,创建以下目录结构:```webserver/├── src/```#### 2. 实现核心代码在WebServer.java中编写以下内容:```javaSystem.out.println(服务器启动在端口: + PORT);

KUpnlfOj的博客 654

Lumerical 教程,包含作者个人理解及相关设计案例 (目前共计184篇,持续更新中)

4138。

u011699626的博客 1606

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

HTTP Server:从头开始构建简单HTTP服务器需要了解的所有内容

文章翻译至: HTTP Server: Everything you need to know to Build a simple HTTP server from scratch HTTP无处不在! 我们访问的每个网站都在HTTP服务器上运行。 您可能会说还有HTTPS服务器。 从技术上讲,HTTPS与HTTP相同,只是HTTPS具有更高的安全性。 许多程序员可能会对HTTP服务器的工作原理以及...

aboutmn的博客 1万+

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

java 手写http服务器,HttpServer

手写 Http 服务器课程目标:熟悉:使用Sokcet编程+Html+Http协议+反射技术+Xml解析完成服务器编写实现案例:手写一个自己的Http服务器,类似Tomcat服务器要求:最好有一定的JavaEE(JavaWeb项目)开发经验什么是 Http 协议?Http 协议:对浏览器客户端 和 服务端 之间数据传输的格式规范Http是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用...

weixin_33726387的博客 1154

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Java:从零开始创建的一个开源的Web服务器

Java:从零开始创建的一个开源的Web服务器 写在前面:最近在学web前后端内容,其中web服务器搭建大多采用现成的tomcat以及serverlet,今天突发奇想想着能不呢自己写一个web服务器,省去大量的对我来讲没什么用的解析过程,这个简单项目由此展开(所以这个项目没有采用任何框架,都是从零开始写的web服务器)

qq_29322325的博客 1227

java轻量级后端应用服务器从零开始一步步搭建到上线运行(一) java 轻量级http服务器框架源码

java轻量级后端应用服务器从零开始一步步搭建到上线运行(一) java 轻量级http服务器框架源码 简介一, 开发 准备和工具二, idea 创建空白项目三, http框架核心源码四, http接口开发五, http服务器本地运行,调试 简介 这是一个轻量级服务器搭建的系列文章,各个功能模块都被分解,一章一章的整合进去,从简单到复杂,从简陋到完善,最终就是一个完整的java后台应用服务器项目....

a704397849的博客 5199

Java实现http服务器

前言 有个需求,需要内嵌http服务,要求体积尽可能小,http并发很小,那么就自行实现一个http服务。其实http只是一种应用层协议:超文本传输协议。传输层协议为TCP。 1. http协议 http协议的内容通过抓包如下: 可以看见Hypertext Transfer Protocol下 标红的是http协议的核心,http header是说明协议,协议mime-type;body才是返回的内容。 2. BIO HTTP demo ...

fenglllle的博客 8489

挚爱原生之node手撸实现服务器

前言 作为程序猿,可以没有女朋友(好像也只能接收找不到的现实),但绝对不能没有格子衫、护发素····和对原生的挚爱,今天,咱们就来手写一个简单的node服务器吧 目标 实现服务器的处理请求,返回响应 实现不同请求方式的处理不同 进阶:实现表单提交文件 实现要点 服务器本质上就是一台电脑,存储着各种各样的资源 接口其实就是一个入口,你给我我要的参数,我给你你要的数据,怎么给,并不神秘,代码实...

weixin_34245082的博客 188

【计网】从零开始学习http协议 --- http的请求与应答

本文详细讲解了什么是http协议,并通过将Linux云服务器的端口开放,实验了浏览器访问服务器进程服务。然后讲解了http协议中的Request 和 Response,并实现了Request的反序列化!!!

叫我龙翔的博客 4920

使用C#开发HTTP服务器系列之Hello World

各位朋友大家好,我是秦元培,欢迎大家关注我的博客。从今天起,我将开始撰写一组关于HTTP服务器开发的系列文章。我为什么会有这样的想法呢?因为人们对Web技术存在误解,认为网站开发是Web技术的全部。其实在今天这样一个时代,Web技术可谓是无处不在,无论是传统软件开发还是移动应用开发都离不开Web技术,所以在我的认识中,任何使用了HTTP协议实现数据交互都可以认为是Web技术的一种体现,而且当我们提及

素履独行 | 元培的个人博客 4万+
上一篇: CRC 循环冗余校验原理 Python 实现
下一篇: Python 的类对于传入的某些参数比如list类型具有修改影响
JintuZheng
博客等级 码龄11年 1483粉丝 109原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值