一.何谓“服务”?
服务就是按照客户的要求来完成客户的相关需求。服务器更具体的表现形式是按照客户的请求来执行某种操作,并返回指定数据给客户(返回响应)。这里返回的数据(即响应)和客户发来的请求,更具体的表现形式通常是字符串。也就是说客户端发给服务器一个包含客户端自身请求的字符串,然后服务端通过解析客户端发来的请求字符串,然后获取客户端的请求,然后完成客户端的相关业务。
二.那么问题来了,服务端如何解析客户端发来的请求字符串呢?
服务端和客户端他们之间素不相识,每个客户端按何种组织方式来发送自己的请求,对于服务器来说完全是不可预期的。因此这就需要一个统一的规范来统一客户端的请求和服务端的响应的发送要求,以及规定一些别的行为规范,于是http协议就合情合理的出现了。现在事情就变成客户端发给服务器一个满足http协议的、包含客户端需求的请求字符串,服务端根据http协议来解析客户端发来的请求字符串,然后获取客户端的需求,然后完成相关的业务,最后返回符合http协议的响应字符串给客户端。
三.“发送”请求,“返回”响应又具体是什么呢?
它们就是客户端和服务器之间通过socket连接执行的一些IO操作。
四.工作流程
客户端建立一个连接到服务端,执行IO操作,把满足http协议的请求字符串发送给服务器,服务器根据http协议来解析客户端发来的请求字符串,然后执行对应操作(即业务),最后把作为返回结果的、满足http协议的响应字符串,通过执行IO操作发送给客户端。因此服务器端和客户端的交互就完成了。
分为以下4个步骤:
1)首先客户端与服务器需要建立连接。
2)建立连接后,客户端发送一个请求给服务器。
3)服务器接到请求后,发送相应的响应信息给客户端。
4)客户端接收服务器所返回的响应信息后,通过浏览器显示在用户的显示屏上,然后客户端断开与服务器的连接。
有关http协议的相关知识在前边博客中已经简单介绍。
五.主要代码
1.SimpleHttpServer.java
package Main;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SimpleHttpServer {
public static void main(String[] args) throws IOException {
//1.创建服务器套接字(设置端口:1234)
ServerSocket serverSocket = new ServerSocket(1234);
//2.创建固定大小(10个大小)的线程池
ExecutorService pool = Executors.newFixedThreadPool(10);
while (true) {
//3.等待客户端来连接服务器(若没有客户端连接上,则在此一直等待)
Socket socket = serverSocket.accept();
//4.把客户端带来的任务交给线程池中的线程去完成
pool.execute(new Task(socket));
}
}
}
2.Task.java
package Main;
import Servlet.*;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
public class Task implements Runnable {
private Socket socket; //客户端套接字
private Map<String, HttpServlet> urlMap=new HashMap<>(); //存储不同的url对应的HttpSerlvet
private HttpServlet notFoundServlet = new NotFoundServlet(); //404对应的HttpSerlvet
private HttpServlet staticServlet = new StaticServlet(); //本地的HttpSerlvet
public Task(Socket socket) {
this.socket=socket;
urlMap.put("/login", new LoginServlet()); //127.0.0.1:1234/login
urlMap.put("/joke.js",new JokeJs