HTTP请求:
一个HTTP请求包含以下三个部分:
请求方法——统一资源定位符(URI)——协议/版本
请求头
实体
请求方法如第一个红方框所示下:
请求头内容如上第二个方框内所示;
请求内容包含有请求参数l上图没有表示出来,简单示例如:lastname = zhang&fristname=san;
它与请求头之间有一个空行,该空行只有CRLF符;
HTTP响应:
与HTTP请求类似也分为三个部分:
协议——状态码——描述
响应头
响应实体段
同样响应实体段与响应头之间也有一个CRLF符空行。响应实体正文是一段html代码段。
了解了这些,就可以用套接字(socket)实现一个简单的web服务器。
首先是服务端代码实现:
public class HttpServer {
public static final String WEB_ROOT = System.getProperty("user.dir")+File.separator + "webroot";
private static final String SHUTDOWN_COMMAND = "/SHUTDOWN";
private boolean shutdown = false;
public static void main(String[] args) {
HttpServer server = new HttpServer();
server.awiat();
}
public void awiat(){
try {
ServerSocket serverSocket = new ServerSocket(8080,1,InetAddress.getByName("127.0.0.1"));
while(!shutdown){
Socket socket = serverSocket.accept();
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
Request request = new Request(inputStream);
request.parse();
Response response = new Response(outputStream);
response.setRequest(request);
response.sendStaticResource();
socket.close();
shutdown = request.getUri().equals(SHUTDOWN_COMMAND);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
请求实体类:
public class Request {
private InputStream inputStream;
private String uri;
public Request(InputStream inputStream) {
this.inputStream = inputStream;
}
public void parse() {
try {
StringBuffer request = new StringBuffer(2048);
int i;
byte[] buffer = new byte[2048];
i = inputStream.read(buffer);
for (int j = 0; j < i; j++) {
request.append((char) buffer[j]);
}
System.out.println(request.toString());
uri = parseUri(request.toString());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private String parseUri(String requestString) {
int index1, index2;
index1 = requestString.indexOf(" ");
if (index1 != -1) {
index2 = requestString.indexOf(" ", index1 + 1);
if (index2 > index1) {
return requestString.substring(index1 + 1, index2);
}
}
return null;
}
public String getUri() {
return uri;
}
响应类response:
public class Response {
private static final int BUFFER_SIZE= 1024;
Request request;
OutputStream outputStream;
public Response(OutputStream outputStream) {
this.outputStream = outputStream;
}
public void setRequest(Request request) {
this.request = request;
}
public void sendStaticResource() throws Exception{
byte[] bytes = new byte[BUFFER_SIZE];
FileInputStream fileInputStream = null;
File file = new File(HttpServer.WEB_ROOT,request.getUri());
if(file != null && file.exists()){
fileInputStream = new FileInputStream(file);
int ch = fileInputStream.read(bytes, 0, BUFFER_SIZE);
while(ch != -1){
outputStream.write(bytes, 0, ch);
ch = fileInputStream.read(bytes, 0, BUFFER_SIZE);
}
}else{
String errorMessage = "HTTP/1.1 404 FILE NOT FOUND \r\n"+
"Content-Type: text/html\r\n"+
"Content-Length: 23\r\n"+"\r\n"+"<h1>File Not Found</h1>";
outputStream.write(errorMessage.getBytes());
}
if(fileInputStream !=null){
fileInputStream.close();
fileInputStream = null;
}
}
}
测试:
启动Httpserver类,打开浏览器,输入127.0.0.1:8080 即可。虽然上述三个类很简单功能不完整,仅供了解web服务器是如何工作的。
github地址:https://github.com/Mrfirewind/simpelWebServer.git
参考书籍:深入剖析TOMCAT