实现一个http服务器(t)

本文介绍了HTTP协议的基本格式,包括请求和响应的结构,重点讲解了Session和Cookie在HTTP中的作用,用于实现会话状态保持。讨论了Cookie的安全问题以及Session作为替代方案的优势,并对比了两者的区别。同时提到了Set-Cookie头部字段在设置Cookie中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需要先了解一下HTTP的协议格式
在这里插入图片描述


http请求

  1. 首行:[方法] + [url] + 版本
  2. Header:请求的属性,冒号分割的键值对;每组属性用\n结尾,遇到空行部分表示header结束
  3. Body:空行的后面的部分全是body,如果body存在,再Header中会有一个Content-length属性来标识body的长度

http响应

  1. 首行:[版本号] + [状态码] + [状态码解释]
  2. Header:请求的属性,冒号分割的键值对;每组属性用\n结尾,遇到空行部分表示header结束
  3. Body:空行的后面的部分全是body,如果body存在,再Header中会有一个Content-length属性来标识body的长度

http常见的header

  1. Content-Type: 数据类型(text/html等)
  2. Content-Length: Body的长度
  3. Host: 客户端告知服务器, 所请求的资源是在哪个主机的哪个端口上
  4. User-Agent: 声明用户的操作系统和浏览器版本信息;
  5. referer: 当前页面是从哪个页面跳转过来的
  6. Cookie: 用于在客户端存储少量信息. 通常用于实现会话(session)的功能;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MyServer {
   
   
    private static final int PORT = 9999;//端口号

    private static final String CHARSET = "UTF-8"; //统一的字符集编码


    public static void main(String[] args) throws IOException {
   
   
        ServerSocket serverSocket = new ServerSocket(PORT);//监听的socket
        ExecutorService poll = Executors.newFixedThreadPool(10);//创建一个10线程的线程池
        while (true){
   
   
            Socket socket = serverSocket.accept();
            poll.submit(new Runnable() {
   
   
                @Override
                public void run() {
   
   
                    try {
   
   
                        BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                        //解析http请求行
                        String httpLine = reader.readLine();//这个就是读了一行
                        System.out.println("=====" + httpLine);
                        String[] httpLineArray = httpLine.split(" ");
                        String requestMethod = httpLineArray[0];
                        String requesturl = httpLineArray[1];
                        String requestVersion = httpLineArray[2];
                        //解析请求头
                        String requestHeader;
                        Map<String,String> headers = new HashMap<>();
                        while ((requestHeader = reader.readLine()) != null && requestHeader.length() != 0){
   
   
                            String headArray[] = requestHeader.split(":");
                            headers.put(headArray[0].trim(),headArray[1].trim());
                        }
                        PrintWriter writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(),CHARSET),true);
                        String content;
                        if ("/307".equals(requesturl)){
   
   
                            writer.println("HTTP/1.1 307 Temporary Redirect");
                            writer.println("Location: http://www.bit.edu.vip");
                            content = "跳转了";
                        }else if ("/404".equals(requesturl)){
   
   
                            writer.println("HTTP/1.1 404 Not Found");
                            content = "<h1>没有找到资源</h1>";
                        }else {
   
   
                            writer.println("HTTP/1.1 200 OK");
                            content = "<h1> 我的sever服务器</h1>";
                        }
                        writer.println("Content-Type: text/html;charset=utf-8");
                        writer.println("Content-Length: " + content.getBytes(CHARSET).length);
                        writer.println();//这是空行
                        writer.println(content.toString());
                        socket.close();
                    } catch (IOException e) {
   
   
                        e.printStackTrace();
                    }
                }
            });
        }
    }
}


Session And Cookie

  • Http是一个无状态协议,就是说这一次请求和上一次请求是没有联系的,互不认识没有关联的.这种无状态的好处是快速.坏处是需要进行用户状态保持的场景时,必须使用一些方式或者手段
  • http是一个无状态的协议,但是访问有些资源的时候往往需要经过认证的用户才能访问,而且需要一直保持在线状态,所以cookie是一种在游览器端解决的方案,将登录认证之后的用户信息保存在本地游览器中,后面每次发起http请求,都会自动携带上该信息,就能到达认证用户,保持用户在线的作用.
    设置cookie的方法在http的Response报头可以携带Set-Cookie字段来完成

在这里插入图片描述
Session

  • 将用户信息保存到本地浏览器中,能解决一定的问题,但是又引进了新的安全问题,一旦Cookie丢失,用户信息泄漏,所以有了另外一种解决方法,将用户敏感信息保存到服务器,而服务器本身采用md5算法或相关算法生成唯一值,而该值保存到客户端浏览器,随后客户端的后续请求,浏览器都会自动携带该id,进而再服务器端认证,达到状态保持的效果.

在这里插入图片描述(http请求 + Cookie(带session - id))
Session VS Cookie

两者有什么区别呢

Cookie 是以文本文件格式存储在浏览器(客户端)中,而Session存储在服务器
因为每次发送http请求,都要携带有效Cookie信息,所以Cookie一般有大小限制,以防止网络压力,一般不超过4k
可以轻松访问cookie值,但是我们无法轻松访问会话值,因此session方案更安全


带Set-Cookie

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SetCookieServer {
   
   
    private static final int PORT = 9999;
    private static final String CHARSET = "UTF-8";

    public static void main(String[] args) throws IOException {
   
   
        ServerSocket serverSocket = new ServerSocket(PORT);
        ExecutorService pool = Executors.newCachedThreadPool();
        while (true){
   
   
            Socket socket = serverSocket.accept();
            pool.submit(new Runnable() {
   
   
                @Override
                public void run() {
   
   
                    try {
   
   
                        Request request = Request.build(socket.getInputStream());
                        Response response = Response.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值