Java写一个简单的Web服务器Socket实现
一、实现思路
1、使用 ServerSocket 监听某一端口,然后等待连接获取 Socket对象。
2、创建一个类 HttpServer 继承 java.lang.Thread 类,重写 run()方法,执行浏览器请求。
3、获得浏览器请求,解析资源文件路径。
4、读取资源文件,响应给浏览器。
二、代码实现
1、ServerSocket 监听端口,获取 Socket对象
package com.httpserver.two;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @description: 使用socket 自己写一个web服务器 ---监听端口,获取socket 对象。
* @version:v1.0
* @author:w
* @date:2018年6月6日上午11:03:36
*
*/
public class WebServer {
public void startServer(int port){
try {
@SuppressWarnings("resource")
ServerSocket serverSocket = new ServerSocket(port);
while(true){
Socket socket = serverSocket.accept();
new HttpServer(socket).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
2、HttpServer.java类 --- 具体作用看方法注释。
package com.httpserver.two;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
/**
* @description: 使用socket 实现 web服务器 --- 具体执行读写操作的。
* @version:v1.0
* @author:w
* @date:2018年6月6日上午11:06:20
*
*/
public class HttpServer extends Thread {
/**
* web资源根路径
*/
public static final String ROOT = "c:/";
/**
* 输入流对象,读取浏览器请求
*/
private InputStream input;
/**
* 输出流对象,响应内容给浏览器
*/
private OutputStream out;
/**
* @description:初始化socket对象,获取对应 输入,输出流
* @param socket
*/
public HttpServer(Socket socket) {
try {
input = socket.getInputStream();
out = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 多线程方法调用
*/
@Override
public void run() {
String filePath = read();
response(filePath);
}
/**
* @description: 读取资源文件,响应给浏览器。
* @param:@param filePath
* 资源文件路径
* @return:void
* @version:v1.0
* @author:w
* @date:2018年6月6日 上午11:42:37
*
*/
private void response(String filePath) {
File file = new File(ROOT + filePath);
if (file.exists()) {
// 1、资源存在,读取资源
try {
BufferedReader reader = new BufferedReader(new FileReader(file));
StringBuffer sb = new StringBuffer();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\r\n");
}
StringBuffer result = new StringBuffer();
result.append("HTTP /1.1 200 ok /r/n");
result.append("Content-Type:text/html /r/n");
result.append("Content-Length:" + file.length() + "/r/n");
result.append("\r\n:" + sb.toString());
out.write(result.toString().getBytes());
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
} else {
// 2、资源不存在,提示 file not found
StringBuffer error = new StringBuffer();
error.append("HTTP /1.1 400 file not found /r/n");
error.append("Content-Type:text/html \r\n");
error.append("Content-Length:20 \r\n").append("\r\n");
error.append("<h1 >File Not Found..</h1>");
try {
out.write(error.toString().getBytes());
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
*
* @description:解析资源文件路径
* @example: GET /index.html HTTP/1.1
* @param:@return
* @return:String
* @version:v1.0
* @author:w
* @date:2018年6月6日 上午11:39:42
*
*/
private String read() {
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
try {
// 读取请求头, 如:GET /index.html HTTP/1.1
String readLine = reader.readLine();
String[] split = readLine.split(" ");
if (split.length != 3) {
return null;
}
System.out.println(readLine);
return split[1];
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
三、代码测试
1、启动服务器
public static void main(String[] args) {
new WebServer().startServer(8000);
}
2、浏览器地址栏输入:
http://localhost:8000/index.html
3、效果如下:
四、总结
1、该示例代码可直接粘贴IDE中运行,无需任何第三方jar包。 简单简洁,便于理解。
2、c盘中,必须有一个 index.html的文件,若存放在其他位置,请修改 HttpServer.ROOT字段,路径位置即可。
3、若出现请求成功,响应页面为空白,请去掉 index.html 页面的 <html>标签试试。--- 至于什么问题导致的,目前还不清楚。 -_-!
4、 index.html 代码参考
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>Hello World! this is my webserver!</h1>
</body>