Java implements a simple Web server

  • 2020-05-05 11:18:54
  • OfStack

It is well known that the communication between the Web server and the client USES the HTTP protocol. HTTP is a standard for client-side and server-side requests and responses (TCP). Since the HTTP protocol is based on the TCP protocol, I'll use Socket in JAVA for this simple Web server. For more detailed information about HTTP, you can refer to the relevant materials for further information.
Before the server is written, let's take a look at the rules for communication between the browser and the server.
First, we use ServerSocket to simulate a server, access it through the browser, and see what the browser requested:


import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

import org.junit.Test;

/**
 * HTTP Protocol testing 
 * 
 * @author jianggujin
 * 
 */
public class HQHttpProtocolTest
{
 @Test
 public void server() throws Exception
 {
  ServerSocket serverSocket = new ServerSocket(80);
  Socket socket = serverSocket.accept();
  InputStream stream = socket.getInputStream();
  int r = -1;
  while ((r = stream.read()) != -1)
  {
   System.out.print((char) r);
  }
 }
}

Running with junit and accessed through a browser: http://127.0.0.1 , we can see that the console outputs the browser's request as follows:


GET / HTTP/1.1
Host: 127.0.0.1
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537
.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8

To better analyze the request content, we wrote an HTML page to submit some data and review the request content again:


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
</head>
<body>
<form method="post" action="http://127.0.0.1?test=123">
<input type="text" name="name"/>
<input type="submit"/>
</form>
</body>
</html>

Enter bob in the input box, click the button to submit, and watch the console output:


POST /?test=123 HTTP/1.1
Host: 127.0.0.1
Connection: keep-alive
Content-Length: 8
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: null
User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537
.36
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8

name=bob

Let's analyze this request:
The first line is composed of three parts, separated by Spaces. The first part is the request method (GET, POST), the second part is the request path and query parameters, and the third part is the HTTP protocol version (HTTP/1.1)
Lines 2 through 10: header information for the request, and the header name and value are separated by:
Line 11: blank
Line 12: submitted form content
In conclusion, we can get the following conclusion: request information first action request method, path and query parameters, HTTP protocol version, by \ r \ n line followed by the request header, the header information between through \ r \ n newline, an empty line after the request header followed, after a blank line followed by an action request data, it is important to note that it only simulates the most simple form is submitted, as for the complex documents submitted, etc., it does not discuss, request content format is slightly different.
So far, we have known the content of the client's request. Next, we will look at the format of the server's response data after receiving the request. We will create a new Web project for testing, and edit the Html page as follows:


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
</head>
<body>this is test page.
</body>
</html>

Start the server, then write the client-side test code to get the data returned by the server:


import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

import org.junit.Test;

/**
 * HTTP Protocol testing 
 * 
 * @author jianggujin
 * 
 */
public class HQHttpProtocolTest
{

 public void server() throws Exception
 {
  ServerSocket serverSocket = new ServerSocket(80);
  Socket socket = serverSocket.accept();
  InputStream stream = socket.getInputStream();
  // BufferedInputStream inputStream = new BufferedInputStream(stream);
  int r = -1;
  while ((r = stream.read()) != -1)
  {
   System.out.print((char) r);
  }
 }

 @Test
 public void client() throws Exception
 {
  Socket socket = new Socket("127.0.0.1", 80);
  BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
   socket.getOutputStream()));
  writer.write("GET /Servlet/test.html HTTP/1.1\r\n");
  writer.write("Host: 127.0.0.1\r\n");
  writer.write("Connection: keep-alive\r\n");
  writer.write("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n");
  writer.write("User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36\r\n");
  writer.write("Accept-Encoding: gzip,deflate,sdch\r\n");
  writer.write("Accept-Language: zh-CN,zh;q=0.8\r\n");
  writer.write("\r\n");
  writer.flush();
  InputStream stream = socket.getInputStream();
  int r = -1;
  while ((r = stream.read()) != -1)
  {
   System.out.print((char) r);
  }
 }
}

Run the program to get the server to return the following:


HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Accept-Ranges: bytes
ETag: W/"129-1456125361109"
Last-Modified: Mon, 22 Feb 2016 07:16:01 GMT
Content-Type: text/html
Content-Length: 129
Date: Mon, 22 Feb 2016 08:08:32 GMT

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
</head>
<body>this is test page.
</body>
</html>

Again, let's examine this return message:
The first line consists of three parts separated by Spaces. The first part is the HTTP protocol version (HTTP/1.1), the second part is the response status code, and the third part is the response status description
Lines 2 through 7 contain response header information, and the response header name and value are separated by:
Line 8: blank
Line 9 to end: response content
In conclusion, we can get the following conclusion: first request information HTTP protocol version, the response status code and the response status description, through \ r \ n response headers, followed by a line between each header information through \ r \ n line, response headers with a blank line, after the response data came in the wake of a blank line, it is important to note that in addition to this kind of response, there are other ways of corresponding chunk, for example, will not be discussed here, can consult the relevant information.

So far, we have finished analyzing the content format of the request from the client and the format of the corresponding content on the server. This is the end of this article, I hope to help you with your study.


Related articles: