Java-based implementation of a simple HTTP server (RPM) This article will detail how to implement a simple HTTP server based on the Java language, the article will mainly introduce three aspects of the content: 1) The basic knowledge of the HTTP protocol, 2) Java.net.Socket class, 3) Java.net.ServerSocket class, after reading this article you can put this server with multi-threaded technology to rewrite a better server.
Because the Web server communicates using the HTTP protocol and therefore calls it an HTTP server, HTTP uses a reliable TCP connection to work, which is a connection-oriented approach, which means that the client and the server each communicate to establish their own connection, it is a stateless connection, When the data transfer is completed, the client and server connections are shut down immediately, which saves the resources of the server and, of course, if you need to transfer large amounts of data, you can set the connection=keep-alive on the request header so that you can reuse this connection channel. The two concepts that are important in the HTTP protocol are: request and (response) That's what I'm going to tell you here. If you want to know more about HTTP then please refer to http://www.w3.org/Protocols/HTTP/1.1/rfc2616.pdf.
An HTTP request consists of three important parts:
Method-uri-protocol/version
Request headers
Entity body
The following is an example of an HTTP request:
post/servlet/default.jsp http/1.1
Accept:text/plain; Text/html
Accept-language:en-gb
Connection:keep-alive
Host:localhost
Referer:http://localhost/ch8/senddetails.htm
user-agent:mozilla/4.0 (compatible; MSIE 4.01; Windows 98)
Content-length:33
content-type:application/x-www-form-urlencoded
Accept-encoding:gzip, deflate
Lastname=franks&firstname=michael
The first line is Method-uri-protocol/version, which is a very important part of how you need to read the client data transfer, URI and protocol and version, here are post/servlet/default.jsp http/ 1.1, our simple server idea is to get the URI from the request and find the resource on your server, such as a static HTML page, and send it to the browser. Remember that the URI is relative to the root directory of your HTTP server, so start with/. The next part is the request header information, which is made up of name:value, which is no longer introduced here. There is a blank line between the header and the entity body called CRLF, which is used to mark the beginning of the entity body, meaning the following is the transmitted data.
HTTP responses and requests are very similar, and also include three parts:
Protocol-status code-description
Response headers
Entity body
Here is a specific example:
http/1.1 OK
server:microsoft-iis/4.0
Date:mon, 3 Jan 1998 13:13:33 GMT
Content-type:text/html
Last-modified:mon, Jan 1998 13:23:42 GMT
content-length:112
Something in HTML style ......... .......
Usually in the J2ME network we need to determine the response status code to determine the next operation, such as 200 for the success of the connection. Now you should know why you're doing it. There is also a CRLF split in the header and entity body.
Now let's take a look at the socket class in Java, the socket is actually an abstraction of the programming language, it provides access to the end of the network is possible, but it does not depend on the programming language, you can use the Java and C language through the socket to communicate, In Java, it's done by Java.net.Socket, and when you're building a socket, you just need to call its constructor.
Public Socket (String host,int Port), where host represents the address or name of the destination host, and port represents the ports, such as 80. When we create an instance of a socket we can communicate, if you want to communicate based on bytes, then you can call Getoutputstream () and getInputStream () To get OutputStream and InputStream objects, if you are based on character communication then you can use PrintWriter and BufferedReader for two times, for example printwriter pw = new PrintWriter (Socket.getoutputstream (), true). The following is a simple code snippet that uses socket communication to implement the ability to send HTTP requests to 127.0.0.1:8080
Java code
- Socket socket = new socket ("127.0.0.1", "8080");
- OutputStream OS = Socket.getoutputstream ();
- Boolean autoflush = true;
- PrintWriter out = new PrintWriter (Socket.getoutputstream (), AutoFlush);
- BufferedReader in = new BufferedReader ( new InputStreamReader (Socket.getinputstream ()));
- Send an HTTP request to the Web server
- Out.println ("get/index.jsp http/1.1");
- Out.println ("host:localhost:8080");
- Out.println ("Connection:close");
- Out.println ();
- Read the response
- Boolean loop = true;
- StringBuffer sb = new StringBuffer (8096);
- while (loop) {
- if (In.ready ()) {
- int i=0;
- While (i!=-1) {
- i = In.read ();
- Sb.append ((char) i);
- }
- loop = false;
- }
- Thread.CurrentThread (). Sleep (50);
- }
- Display the response to the out console
- System.out.println (Sb.tostring ());
- Socket.close ();
Next introduce the use of the ServerSocket class corresponding to the socket class, unlike the socket on behalf of the client, ServerSocket is on behalf of the server side, because it must be on a port constantly monitoring whether a client connection comes in. By calling ServerSocket's constructor we can establish a server that listens on a specific port. For example
New ServerSocket (8080, 1, inetaddress.getbyname ("127.0.0.1"));
So we set up the ServerSocket on the 8080 port of this machine. When you call ServerSocket's accept () method, the method returns a socket object only if there is a connection, so you can use this instance to accept or send the data. Remember to call the Clos () method to release the resource when we have finished transmitting the data.
In the previous article we covered the basics of the HTTP protocol, as well as two important classes of sockets and Socketserver classes in Java, and we'll show you how to implement a Java-based HTTP server.
The HTTP server consists mainly of three classes: Httpserver, request, and response. Where the entry of the program is in the Httpserver class, it calls the await () method, which causes the server to start waiting for the client to connect. When the client connects, it sends the static page content to the client browser. These three classes are described below:
1:httpserver class
Httpserver needs to have a root directory of the server that is defined in the Web_root variable:
public static final String web_root =system.getproperty ("User.dir") + File.separator + "Webroot"; When we run the server, we can specify the value of the environment variable user.dir with the-D option. The most important method in this class is the await () method, which reads as follows:
public void await () {
ServerSocket serversocket = null;
int port = 8080;
try {
ServerSocket = new ServerSocket (port, 1, Inetaddress.getbyname ("127.0.0.1"));
}
catch (IOException e) {
E.printstacktrace ();
System.exit (1);
}
Loop waiting for a request
while (!shutdown) {
Socket socket = NULL;
InputStream input = null;
OutputStream output = null;
try {
Socket = Serversocket.accept ();
input = Socket.getinputstream ();
Output = Socket.getoutputstream ();
Create Request object and parse
Request Request = new request (input);
Request.parse ();
Create Response Object
Response Response = new Response (output);
Response.setrequest (Request);
Response.sendstaticresource ();
Close the socket
Socket.close ();
Check if the previous URI is a shutdown command
shutdown = Request.geturi (). Equals (Shutdown_command);
}
catch (Exception e) {
E.printstacktrace ();
Continue
}
}
}
The await () method constructs an instance of ServerSocket, which is passed to the request class when the client connects in, and the Socket.getoutputstream () is parsed by the Socket.getinputstream () Pass to the response class, then pass the request object to response, and finally call the Response.sendstaticresource () method to send the data to the client. Socket.close () After monitoring is not accepted to the command to shut down the server, if so, jump out of the Loop end program.
2. Request Class
The main purpose of the request class is to encapsulate the HTTP request, which has a constructor for the InputStream type parameter
Public Request (InputStream input) {
This.input = input;
}
It also has an important type of string member variable uri,request is the purpose of extracting the URI from the InputStream, which is implemented by two functions
public void Parse () {
Read a set of characters from the socket
StringBuffer request = new StringBuffer (2048);
int i;
byte[] buffer = new byte[2048];
try {
i = input.read (buffer);
}
catch (IOException e) {
E.printstacktrace ();
i =-1;
}
for (int j=0; j<i; J + +) {
Request.append ((char) buffer[j]);
}
System.out.print (Request.tostring ());
URI = Parseuri (request.tostring ());
}
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;
}
Where the Parseuri (string request) method is a private method, it parses the string argument to return two spaces between the strings, which follows the definition rules for HTTP requests, and if you are not sure you can refer to one of the Java-based implementations of the HTTP server.
2.Response class
The two important member variables of response are the OutputStream type of output and the request of the Requeset type, which is the function of obtaining a URI from the instance of request, and then Web_ Root adds the absolute path to the file, and then reads the contents of the file and writes it to Socket.getoutputstream ().
public void Sendstaticresource () throws IOException {
byte[] bytes = new Byte[buffer_size];
FileInputStream FIS = null;
try {
File File = new file (Httpserver.web_root, Request.geturi ());
if (file.exists ()) {
FIS = new FileInputStream (file);
int ch = fis.read (bytes, 0, buffer_size);
while (Ch!=-1) {
Output.write (bytes, 0, ch);
ch = fis.read (bytes, 0, buffer_size);
}
}
else {
File not found
String errormessage = "http/1.1 404 File Not found/r/n" +
"content-type:text/html/r/n" +
"content-length:23/r/n" +
"/r/n" +
"Output.write (Errormessage.getbytes ());
}
}
catch (Exception e) {
Thrown if cannot instantiate a File object
System.out.println (E.tostring ());
}
finally {
if (fis!=null)
Fis.close ();
}
}
Here's how to run the application, first you get the source code from the following address: http://www.onjava.com/onjava/2003/04/23/examples/ Howwebserverswork.zip, get it to your D-disk. For example, the temp directory, it includes three directories src Lib Webroot where Webroot has a index.html file for testing purposes. Run from command
CD Temp
Javac-d. Src/ex01/pyrmont/*.java
This will appear in the current directory (d:/temp) Ex01/pyrmont directory, which is compiled by the class file, the next run
Java-duser.dir=d:/temp Ex01.pyrmont.HttpServer
Then enter http://localhost:8080/index.html from the browser, so you can see the static page index.html sent to you by the server.
Java-based implementation of simple HTTP server (RPM)