本系列教程将和您一起探讨如何利用Java语言一步一步实现自己的web服务器。
1 需求描述
第1讲我们要实现的效果是:当我们在浏览器的地址栏输入localhost:8080的时候,我们会看到"hello,this is my web server!"。如下:
2 实现
做任何事情都不能太急,对于编程来说也不例外。以上的案例虽然简单,但却是我们编写web服务器的非常关键的一步,麻雀虽小,五脏俱全。
2.1 基础知识
首先我们来分析一下,为了实现上面的功能,我们需要具备哪些基础知识。
1) CS架构介绍
CS架构是一种非常常见的软件架构,主要由两部分组成:客户端和服务器端即C端和S端。
图 2-1 CS架构
其一般的交互流程为:客户端发送一条请求给服务器,服务器在收到请求后,解析处理该请求,并将结果以响应的方式返回给客户端。
那么在我们要要实现的需求中,客户端特定为浏览器,请求特指http请求,响应特指http响应。
一般情况CS架构的软件,我们需要分别开发C端和S端的程序,但是由于本题客户端就是我们日常使用的浏览器,所以我们不需要开发C端程序,所以仅需要开发服务器端程序。
这是我们实现需求需要了解的第一个基础知识。
2)http请求和响应
有了上面的基础知识后,接下来我们需要具体的了解,这个http请求长什么样,http响应长什么样?
下面我们来看一个具体的请求和响应报文的格式:
http请求报文:
GET / HTTP/1.1
Host: www.baidu.com.cn
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0(Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/56.0.2924.87 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,en;q=0.6,zh-TW;q=0.4,ja;q=0.2
http响应报文:
HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 21005
Content-Type: text/html
Server: Microsoft-IIS/7.0
X-Powered-By: ASP.NET
Date: Tue, 07 Mar 2017 01:59:58GMT
3)Socket编程
有了以上的基础知识之后,我们还需要了解Java在实现CS架构时使用的具体技术,那就是socket编程。socket编程的入门其实并不难,下面为大家做简要介绍:
-
socket编程可以分为两部分,一部分为服务器端的编程,另外一部分为客户端。对于服务器端我们使用ServerSocket类,客户端使用Socket类。
- 一旦建立连接后,获取了客户端的socket对象,接下来就可以通过socket对象的InputStream来读取请求,而OutputStream来写响应。
2.2 实现
有了上面的3个基础知识点后,接下来我们可以开始编程实现了。
主要的业务流程为:
-
服务器端利用ServerSocket开启8080端口开始监听;
-
当有客户端发起的http请求时,接受该客户端读取http请求,进行相关处理;
- 返回http响应。
具体的代码实现如下:
public class WebServer {
private ServerSocket serverSocket;
public WebServer() {
try {
// 开启8080端口监听
serverSocket = newServerSocket(8080);
} catch (IOException e) {
e.printStackTrace();
}
}
public void run(){
try {
Socket socket =serverSocket.accept();
// 读取http请求
BufferedReader reader = newBufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while (!(line =reader.readLine()).equals("")) {
System.out.println(line);
}
// 返回http响应
PrintWriter writer = newPrintWriter(socket.getOutputStream());
writer.print("HTTP/1.1 200OK\r\n");
writer.print("\r\n");
writer.print("hello, thisis my web server!");
writer.flush();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new WebServer().run();
}
}
3 总结
我们已经按照需求实现了相关功能,但是细心的你可能会发现以下的问题:
1)浏览器刷新一次,服务器端程序就终止了;
2)这个服务器能不能作为静态网页html服务器呢?
3)。。。