Simple Http server based on Java

Last time I saw a Java based http server code, its function is very simple, but it uses a lot of knowledge learned, which is very interesting, so I imitated and wrote one. At the beginning, I encountered a little problem (this problem feels more difficult than this code). Now the basic problems have been solved. You can see about that problem My blog . It's very nice to deploy it to the server. I'd like to share it with you.

Project presentation address: What are you looking at

Function introduction

Enter the website, you can access a simple picture through the browser, but I think this thing is quite interesting.
Here is all the code. You can copy it directly and use it. If you test it locally, enter it directly: localhost:10000 Just.

code

HttpServer class

package com.dragon;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class HttpServer {
	private static ServerSocket server;
	
	/**
	 * Start service
	 * */
	public void start() {
	    try {
	    	server = new ServerSocket(10000);
	    	System.out.println("Service started successfully...");
	    	this.receiveRequest();
	    } catch (IOException e) {
	    	e.printStackTrace();
	    	System.out.println("Service start failed!");
	    }
	}

	
	/**
	 * Receive request
	 * */
	public void receiveRequest() {
		ExecutorService pool = Executors.newFixedThreadPool(10);
		while (true) {
			try {
				Socket client = server.accept();
				System.out.println("user"+client.getInetAddress().toString()+"Establish a connection" + client.toString());
				pool.submit(new Connection(client));  //Use threads to process every request.
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

Connection class

package com.dragon;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class Connection implements Runnable {
	private static final String BLANK = " ";
	private static final String CRLF = "\r\n";
	private byte[] content;
	private byte[] header;
	private Socket client;
	
	public Connection(Socket client) {
		this.client = client;
	}
	
	@Override
	public void run() {
		//The request is not processed here, but will respond after receiving the request, regardless of the request
		//Here, we simulate the most primitive functions of the server: request and response.
		this.response();
		System.out.println("Thread execution is over!");
	}
	
	/**
	 * Receiving request information is a simple simulation here, only get requests can be received here.
	 * @throws IOException 
	 * */
	public String getRequestInfo(InputStream in) throws IOException {
		//Read only the first line, that's all we need
		StringBuilder requestLine = new StringBuilder(80);
		while (true) {
			int c = in.read();
			if (c == '\r' || c == '\n' || c == -1) break;
			requestLine.append((char)c);
		}
		return requestLine.toString();
	}
	
	/**
	 * Response information
	 * */
	public void response() {
		InputStream in = null;
		OutputStream out = null; 
		try {
			in = new BufferedInputStream(client.getInputStream());
			out = new BufferedOutputStream(client.getOutputStream());   //Get output stream
			String requestInfo = this.getRequestInfo(in);           //If the data sent by the client is not read, the server will make an error,
			System.out.println(requestInfo);                        //Because it violates the rules of Http protocol
		} catch (IOException e1) {
			e1.printStackTrace();
		}       //Get input stream
		
		
		//Response data
		Path filepath = Paths.get("/", "home", "Alfred", "kkk.jpeg"); //Path to picture
		File file = filepath.toFile();
		String contentType = null;  //MIME type of file
		try {
			content = Files.readAllBytes(file.toPath());           //Use Files tool class to read Files at one time
			contentType = Files.probeContentType(file.toPath());   //Get MIME type of file
			long length = file.length();                           //Get file byte length
			header = this.getHeader(contentType, length);          // Fill response header
 		} catch (IOException e) {
			e.printStackTrace();
		}
		
		try {
			out.write(header);        //Write Http message header
			out.write(content);       //Write the data part of Http message
			out.flush();              //Refresh the output stream to ensure that the data in the buffer has been sent
			
			System.out.println("Total message size (bytes):" + (header.length + content.length));
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("Customer disconnected or failed to send!");
		} finally {
			try {
				if (client != null) {
					client.close();
				}
				System.out.println("The request is over");
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
    }
	
	//Response head
	private byte[] getHeader(String contentType, long length) {
		return new StringBuilder()
				.append("HTTP/1.0").append(BLANK).append(200).append(BLANK).append("OK").append(CRLF)  // Response header
				.append("Server:"+"CrazyDragon").append(CRLF)
				.append("X-Words").append("I love you yesterday and today!").append(CRLF)  //Add a custom Http Header, although this method has been disabled.
				.append("Date:").append(BLANK).append(this.getDate()).append(CRLF)
				.append("Content-Type:").append(BLANK).append(contentType).append(CRLF) //The content type of the file is available in Java.
				.append("Content-Length:").append(BLANK).append(length).append(CRLF).append(CRLF)
				.toString()
				.getBytes(Charset.forName("UTF-8"));
	}
	
	//Get time
	private String getDate() {
		Date date = new Date();
		SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss 'GMT'", Locale.US);
		format.setTimeZone(TimeZone.getTimeZone("GMT")); // Set time zone to GMT  
		return format.format(date);
	}
}


Note: the image path here is the path above my computer. If you need to test, you need to change it to your local file path.

Test class

package com.dragon;

public class Test {
	public static void main(String[] args) {
		HttpServer httpServer = new HttpServer();
		httpServer.start();
	}
}

explain

This demo is very simple. I have also written a bit more complex based on this, but there are still some problems, some of which are not handled very well, mainly because I only have a simple understanding of the HTTP protocol, but more details are not clear. This example is good for learning the relationship between the transport layer (TCP) and the application layer (HTTP) of the computer network.

Tags: Java socket network

Posted on Thu, 18 Jun 2020 22:01:12 -0400 by Rob the R