socket编程-HTTP服务·

socket编程入门,需要实现的目标:

1,不用框架利用socket编程实现一个http服务框架

2,实现基本的Request/Response封装

3, 思考io和线程模型的关系

首先我们了解一下网络插槽socket,当客户端和服务端在进行交互的时候,会分别产生一个socket,然后这两个socket进行交互,比如客户端想发送信息的时候,先发给socket,接收信息会从socket里读, 这里可以看出socket类似于文件,其实很多操作系统把socket封装成了文件。 

服务端线程模型:

 当我们的操作系统接收到客户端发出的web请求的时候,它会先把这个请求(比如tcp连接的请求)扔到Pending Queue里面,如果满了操作系统会拒绝请求,否则这个请求不断的积累到队列里,直到某一个线程进行accept这个系统调用,这个系统调用会从队列里拿出一个请求,接收之后会在操作系统内核中形成socket文件,这个socket文件对应着资源的FD(可以理解为操作文件资源的东西,其实就是socket),因为具体的文件在内核中,用文件的是具体的线程,这个线程不断循环,不断接收请求生成对应的FD,然后由工作线程读取socket的内容,分析其中的内容,处理完后写入socket文件,操作系统监听到文件被写入后,会把结果送到网卡,通过网络传给请求方。

第一个httpserver:

package com.hai;

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

/**
 * @author caohailiang
 * @date 2022/6/27-17:15
 */
public class RawHttpServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(8001);
        // Main Thread
        while (true){
            // Blocking---
            // Thread--->sleep
            Socket socket = serverSocket.accept();
            // socket来操控内核中的文件
            System.out.println("A socket created");
            DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(dataInputStream));
            StringBuilder stringBuilder = new StringBuilder();
            String line="";
            // Readline -> line end '\n'
            while (!(line=bufferedReader.readLine()).isEmpty()){
                stringBuilder.append(line);
            }
            String request = stringBuilder.toString();
            System.out.println(request);
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            bufferedWriter.write("HTTP/1.1 200 ok\n\nHello World!\n");
            bufferedWriter.flush();
            socket.close();

        }
    }
}

抽象成类:

public class Step1Server {
    ServerSocket serverSocket;
    Function<String,String> handler;
    public Step1Server(Function<String,String> handler){
        this.handler=handler;

    }
    // pending Queue
    public void listen(int port) throws IOException {
        serverSocket = new ServerSocket(port);
        while (true){
           this.accept();
        }
    }
    void accept() throws IOException {
        // Blocking---
        // Thread--->sleep
        try {
            Socket socket = serverSocket.accept();
            // socket来操控内核中的文件
            System.out.println("A socket created");
            DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(dataInputStream));
            StringBuilder stringBuilder = new StringBuilder();
            String line="";
            // Readline -> line end '\n'


            while (true){
                line=bufferedReader.readLine();
                if(line==null||line.isEmpty()){
                    break;
                }
                stringBuilder.append(line+'\n');
            }
            String request = stringBuilder.toString();
            System.out.println(request);
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            String response = this.handler.apply(request);
            bufferedWriter.write(response);
            bufferedWriter.flush();
            socket.close();
        } catch (SocketException e) {
            e.printStackTrace();
        }

    }
    public static void main(String[] args) throws IOException {
        Step1Server server = new Step1Server(req -> {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "HTTP/1.1 200 ok\n\nHello World1!\n";
        });
        server.listen(8001);


    }

http服务的多线程优化:

public class Step2Server {
    ServerSocket serverSocket;
    Function<String,String> handler;
    public Step2Server(Function<String,String> handler){
        this.handler=handler;

    }
    // pending Queue
    public void listen(int port) throws IOException {
        serverSocket = new ServerSocket(port);
        while (true){
           this.accept();
        }
    }
    void accept() throws IOException {
        // Blocking..
        Socket socket = serverSocket.accept();
        new Thread(()->{
            try {
                this.hander(socket);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }
    void hander(Socket socket) throws IOException {
        // Blocking---
        // Thread--->sleep
        try {
           // Socket socket = serverSocket.accept();
            // socket来操控内核中的文件
            System.out.println("A socket created");
            DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(dataInputStream));
            StringBuilder stringBuilder = new StringBuilder();
            String line="";
            // Readline -> line end '\n'


            while (true){
                line=bufferedReader.readLine();
                if(line==null||line.isEmpty()){
                    break;
                }
                stringBuilder.append(line+'\n');
            }
            String request = stringBuilder.toString();
            System.out.println(request);
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            String response = this.handler.apply(request);
            bufferedWriter.write(response);
            bufferedWriter.flush();
            socket.close();
        } catch (SocketException e) {
            e.printStackTrace();
        }

    }
    public static void main(String[] args) throws IOException {
        Step2Server server = new Step2Server(req -> {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "HTTP/1.1 200 ok\n\nHello World1!\n";
        });
        server.listen(8001);
    }
}


    

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值