手写一个简单的Http服务器

什么是Http协议?

Http协议: 对浏览器客户端 和 服务器端 之间数据传输的格式规范

Http是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且HTTP-NG(Next Generation of HTTP)的建议已经提出。
HTTP协议的主要特点可概括如下:
1.支持客户/服务器模式。
2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

Http是使用Socket中的TCP协议实现,基于请求(客户端)、响应(服务器端)

实例:http://127.0.0.1:8080/项目路径

Http协议分为请求报文和响应报文

请求模式 Get、Post、Delete

默认Http请求参数(请求报文)

GET / HTTP/1.1

Host: 127.0.0.1:8080

Connection: keep-alive

Cache-Control: max-age=0

Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2783.4 Safari/537.36

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

Accept-Encoding: gzip, deflate, sdch

Accept-Language: zh-CN,zh;q=0.8

Cookie: Hm_lvt_b43c1c82b09cda6b125e6981fbde442c=1487946887,1487950668,1488114252; CNZZDATA1259976290=1895288300-1478441025-%7C1488116464

Http响应报文

HTTP响应报文与HTTP请求报文是对应的,也是分为三个部分。

  1、响应行

  2、响应头

  3、响应体

项目结构图:

上代码

封装响应的数据类
package cn.liuzhiw.server;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Date;

/**
 * 封装响应的数据类
 * Created by 刘志威 on 2018/4/24.
 */
public class Response {
    //空格
    private final String BLANK="  ";
    //换行
    private final String BR="\r\n";
    //显示Http响应头
    private StringBuffer responseData;
    //封装网页信息
    private StringBuffer responseInfo;
    //字符缓冲输出流
    private BufferedWriter bufferedWriter;
    //响应的长度
    private long len;
    //初始化配置
    public Response(OutputStream outputStream){
        responseData=new StringBuffer();
        responseInfo=new StringBuffer();
        bufferedWriter=new BufferedWriter(new OutputStreamWriter(outputStream));
    }
    //创建头部信息
    private void createHeadInfo(int code){
        responseData.append("HTTP/1.1");
        responseData.append(BLANK);
        responseData.append(code + "").append(BLANK);
        switch (code){
            case 200:
                responseData.append("ok");
                break;
            case 404:
                responseData.append("not found");
                break;
            case 500:
                responseData.append("server error");
                break;
            default:
                break;
        }
        responseData.append("Date:").append(new Date()).append(BR);
        responseData.append("Content-Type: text/html;charset=UTF-8").append(BR);
        responseData.append("Content-Length:").append(len).append(BR);
        responseData.append(BR);
    }

    /**
     * 填充页面类容
     * @param str
     * @return
     */
    public Response print(String str) {
        responseInfo.append(str);
        len += str.getBytes().length;
        return this;
    }
    /**
     * 发送数据
     * @throws IOException
     */
    public void connect(int code) throws IOException {
        createHeadInfo(code);
        bufferedWriter.append(responseData.toString());
        bufferedWriter.append(responseInfo.toString());
        //刷新
        bufferedWriter.flush();
        //关闭
        bufferedWriter.close();
    }
}

  

服务器核心配置类
package cn.liuzhiw.server;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

/**
 * 服务器核心配置类
 * Created by 刘志威 on 2018/4/24.
 */
public class Server4 {
    //socket服务端
    private ServerSocket serverSocket;
    //端口号
    private final int PORT=8080;
    /**
     * 启动服务器
     */
    public void start() throws IOException {
        System.out.println("服务器启动成功.........");
        //监听服务器
        serverSocket=new ServerSocket(PORT);
        //接受客户端数据
        acceptClient();
        //关闭链接
        closeServer();

    }

    /**
     * 接受客户端数据
     * @throws IOException
     */
    public void acceptClient() throws IOException {
        //拿到socket客户端对象
        Socket accept = serverSocket.accept();
        //拿到输入流
        InputStream inputStream = accept.getInputStream();
        byte []data=new byte[20480];
        int read = inputStream.read(data);
        String message = new String(data, 0, read);
        System.out.println("客户端发送来的数据:"+message);
        //响应回去数据
        Response response=new Response(accept.getOutputStream());
        response.print("<html><head><title>响应页面</title></head><body>响应页面成功</body></html>");
        response.connect(200);
    }
    /**
     * 关闭链接
     * @throws IOException
     */
    public void closeServer() throws IOException {
        if (serverSocket!=null){
            serverSocket.close();
        }
    }
}

  

服务器启动入口
package cn.liuzhiw.app;

import cn.liuzhiw.server.Server4;

import java.io.IOException;

/**
 * 服务器启动入口
 * Created by 刘志威 on 2018/4/24.
 */
public class App {
    public static void main(String[] args) throws IOException {
        Server4 server=new Server4();
        server.start();
    }
}

  html请求的页面

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Http服务器post方式提交参数</title>
</head>
<body>
    <pre>
     method:请求方式 get/post
     get:数据量小,安全性不高  默认方式
     post:量大,安全性相对高
     action:请求的服务器路径
     id:编号:前端区分唯一,js使用
     name:名称后端(服务器)区分唯一性,获取值
           只要提交数据给后台,必须存在name;

    </pre>
   <form action="http://127.0.0.1:8080/index" method="post">
    用户名称:<input type="text" name="uname" id="uname">
    用户面:<input type="password" name="pwd" id="pwd">
   <input type="submit">
   </form>
</body>
</html>

页面效果和后台效果

原文地址:https://www.cnblogs.com/liuzhiw/p/8934430.html

时间: 2024-07-30 17:52:45

手写一个简单的Http服务器的相关文章

如何用PHP/MySQL为 iOS App 写一个简单的web服务器(译) PART1

原文:http://www.raywenderlich.com/2941/how-to-write-a-simple-phpmysql-web-service-for-an-ios-app 作为一个iPhone/iPad开发者,能够自己写一个简单的web服务器将是很有用的. 例如,你可能希望在软件启动时显示一些来自服务器的更新,或者在服务器端保存一些用户数据.除了你的想象力,没有什么能限制你了. 在第一篇中,我们将会一步一步的建立一个web服务器,基于promo code system(促销码系

利用SpringBoot+Logback手写一个简单的链路追踪

目录 一.实现原理 二.代码实战 三.测试 最近线上排查问题时候,发现请求太多导致日志错综复杂,没办法把用户在一次或多次请求的日志关联在一起,所以就利用SpringBoot+Logback手写了一个简单的链路追踪,下面详细介绍下. 一.实现原理 Spring Boot默认使用LogBack日志系统,并且已经引入了相关的jar包,所以我们无需任何配置便可以使用LogBack打印日志. MDC(Mapped Diagnostic Context,映射调试上下文)是log4j和logback提供的一种

用python3写一个简单的http服务器

# Written by Vamei import socket # Address HOST = '' PORT = 8000 # Prepare HTTP response text_content = '''HTTP/1.x 200 OK Content-Type: text/html <head> <title>WOW</title> </head> <html> <p>Wow, Python Server</p>

python web编程(一): web流程,手写一个简单的web框架

# -*- coding: utf-8 -*-__author__ = 'xzq' '''1. HTTP: 特点: 1>. 请求/响应模式 2>. 无状态协议, Client每一次访问都会被Server当作是第一次访问 (Cookie, Session) Request: POST /index.html HTTP/1.1 # 请求方法 url 协议版本 Header: Host: www.bilibili.com # 请求域名 --> DNS Connection: keep-aliv

手写一个模块化的 TCP 服务端客户端

前面的博客 基于 socket 手写一个 TCP 服务端及客户端 写过一个简单的 TCP 服务端客户端,没有对代码结构进行任何设计,仅仅是实现了相关功能,用于加深对 socket 编程的认识. 这次我们对整个代码结构进行一下优化,使其模块化,易扩展,成为一个简单意义上的“框架”. 对于 Socket 编程这类所需知识偏底层的情况(OS 协议栈的运作机制,TCP 协议的理解,多线程的理解,BIO/NIO 的理解,阻塞函数的运作原理甚至是更底层处理器的中断.网卡等外设与内核的交互.核心态与内核态的切

通过python 构建一个简单的聊天服务器

构建一个 Python 聊天服务器 一个简单的聊天服务器 现在您已经了解了 Python 中基本的网络 API:接下来可以在一个简单的应用程序中应用这些知识了.在本节中,将构建一个简单的聊天服务器.使用 Telnet,客户机可以连接到 Python 聊天服务器上,并在全球范围内相互进行通信.提交到聊天服务器的消息可以由其他人进行查看(以及一些管理信息,例如客户机加入或离开聊天服务器).这个模型如图 1 所示. 图 1. 聊天服务器使用 select 方法来支持任意多个客户机 聊天服务器的一个重要

(2)自己写一个简单的servle容器

自己写一个简单的servlet,能够跑一个简单的servlet,说明一下逻辑. 首先是写一个简单的servlet,这就关联到javax.servlet和javax.servlet.http这两个包的类,其中一个比较重要的接口就是:javax.servlet.Servlet,所有的servlet必须实现实现或者继承实现该接口的类. Servlet接口有五个方法: public void init(ServletConfig config) throws ServletException publi

创建一个简单的 MDM 服务器(2)

四.实现 server URL 接下来以推送最简单的锁屏命令为例,演示如何实现从服务器推送完整的 MDM 消息给注册设备. 首先实现一个简单的Jsp 页面.页面中是一个 html 表单,在<select>标签中我们会列出所有注册设备的 UUID(当然列出设备名称会更好),当你选择一个UUID,点击submit 按钮,服务器会向这个设备推送锁屏命令. servlet lock 来负责处理这个表单: Stringudid=request.getParameter("select1&quo

写一个简单的servlet

昨天写完hibernate的小demo后,想写一个简单structs2,但是发现好像自己连servlet都忘了怎么写了,所以一切从头开始,先写一个简单servlet把 第一步 肯定是建立项目了,打开自己eclipse(myeclipse,sts,idea).然后file->new->java project.这里肯定会有疑问,为啥不建立一个web project呢.呃,原因很简单,因为要从头来,一切都从头来呗,web project里 web方面的属性都给配置好了,就起不到学习的作用了. 名字