Java-based web server implementation [Z]

Source: Internet
Author: User
Tags date array final header socket version thread tostring
Web|web Service |web Server Java-based Web server working principle 1

A WEB server is also called an HTTP server, which communicates with the client through the HTTP protocol. This client usually refers to a Web browser. A Java-based WEB server uses two important classes, Java.net.Socket and Java.net.ServerSocket, and communicates over HTTP messages. So this article starts with the discussion of HTTP with these two classes, and then I'll explain a simple WEB application related to this article.

The hypertext Transfer Protocol (HTTP)

HTTP is a protocol that enables WEB servers and browsers (clients) to send and receive data over the Internet. It is a request, response protocol--the client sends a request, and the server responds to the request. HTTP uses a reliable TCP connection, typically a TCP 80 port. Its first version is http/0.9 and then replaced by http/1.0. The current version is http/1.1, defined by RFC2616 (. pdf).

This section mainly corresponds to HTTP 1.1, enough to allow you to fully understand the messages sent by Web server programs. If you are interested in more detailed knowledge, you can refer to RFC2616.

In HTTP, the client always initiates a transaction by establishing a connection and sending an HTTP request. The server cannot take the initiative to contact the client or issue a callback connection to the client. Both the client and the server can interrupt a connection ahead of time. For example, when downloading a file in a browser, you can interrupt the download of the file by clicking the "Stop" button and turn off the HTTP connection to the server.

HTTP Request

An HTTP request contains three parts:

Method-uri-protocol/version Method-Address-version
Request Header Header
Entity Body Request Entity


The following is an instance 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 method-uri-protocol/version on the first line of the request:

post/servlet/default.jsp http/1.1


Where POST is the type of request. Each client HTTP request can be one of many request types specified in the HTTP specification. HTTP 1.1 supports seven kinds of requests, which are get,post,head,options,put,delete,trace. Where get and POST are the two types of requests that are frequently used in Internet applications.

The URI completely specifies the Internet resources. A URI is usually resolved to a relative server's root directory. In this way, it should always start with a '/' prefix. A URL is actually a type of URI.

Version refers to the HTTP protocol versions that are used by the HTTP request.

The request header contains some useful information about the client environment and the requesting entity. For example, it contains the language set by the browser, the length of the entity, and so on. Each request header is separated by a carriage return line feed (CRLF).

A very important blank line separates the request header from the entity, which marks the beginning of the entity content. Some Internet development books consider this CRLF blank line to be the fourth part of the HTTP request.

In the above HTTP request, the entity is simply the following line:

Lastname=franks&firstname=michael


In a typical HTTP request, the request entity content is much longer.

HTTP response

Like the request, the HTTP response is made up of three parts:

Protocol-status code-description Protocol Status Description Code
Response Headers Response Header
Entity Body Response Entity


The following is an example of an HTTP response:

http/1.1 OK
server:microsoft-iis/4.0
Date:mon, 3 1998 13:13:33 GMT
Content-type:text/html
Last-modified:mon, 1998 13:23:42 GMT
content-length:112

<title>http Response example</title>Welcome to Brainy Software
</body>


The first line of the response header resembles the first line of the request header, telling you that the protocol used is HTTP 1.1, the request succeeds (200=success), and there is no problem.

The response header similar to the request header also contains some useful information. The response entity responds to the HTML content of itself. The header is separated from the entity by the empty line (CRLF) in which the carriage return wraps.

Socket class

A socket is the endpoint of a network connection that allows an application to be read and written from the Web. Two of applications on different computers can communicate with each other by sending and receiving byte streams. To send a message to another application, you need to know its IP address and its socket port number. In Java, a socket is implemented with Java.net.Socket.

To create a socket, you can use one of several build methods in the socket class. One of these accepts a host name and a port number as an argument:

New Socket ("yahoo.com", 80);


Once you have successfully created an instance of the Socket class, you can use it to send and receive byte streams. To send a byte stream, you need to call the Getoutputstream method of the socket class to get a Java.io.OutputSteam object. To send text to a remote program, you usually need to create a Java.io.PrintWriter object from the returned outputstream. To receive a byte stream from the other end of the connection, you need to call the getInputStream method of the socket class, which returns a Java.io.InputStream object.

The following code creates a socket (127.0.0.1 represents a local host) that can communicate with a local HTTP server, sends an HTTP request, and receives a response from the server. It also creates a StringBuffer object to accept the response and prints it to the console.

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 ();


Note To get the correct response from the Web server, you must send an HTTP request compiled with the HTTP protocol. If you look at the HTTP section above, you should be able to understand the HTTP request in the above code.

Editor's note: This article is excerpted from Budi's own published book <tomcat Insider. You can get more relevant information on his website.


Java-based Web server working principle 2
Author: fajaven Time: 2003.09.12 17:00:38
ServerSocket class

The socket class describes a "client" socket that needs to be used when you need to create a connection to a remote service program. If you want to implement a service program, such as an HTTP server or an FTP server, you need a different approach. This is because your server must be serviced at any time and it does not know when there will be a client program that needs to connect to it.

For this purpose, you need to use the Java.net.ServerSocket class, which is an implementation of the server-side socket. The server-side socket waits for a connection request from the client. Once it receives a connection request, it creates a socket instance to communicate with the client.

To create a server-side socket, you need one of the four build methods provided by the ServerSocket class. You need to specify the IP address and port number on which the server-side socket listens. More typically, this IP address can be 127.0.0.1, meaning that the server-side socket is listening on the local machine. The IP address on which the server-side socket is listening refers to the binding address. Another important attribute of server-side sockets is the queue length, which is the maximum request queue length accepted before it rejects the request.

One of the ways to build the ServerSocket class is as follows:

Public serversocket (int port,int backlog,inetaddress bindingaddress);


For this build method, the binding address must be an instance of the Java.net.InetAddress class. An easy way to create an object of a inetaddress class is to call its static method Getbyname, passing a string containing the hostname.

Inetaddress.getbyname ("127.0.0.1");


The following code creates a server-side socket that listens on the local machine's 8080 port and restricts the queue length to 1.

New ServerSocket (8080,1,inetaddress.getbyname ("127.0.0.1"));


Once you have a ServerSocket instance, you can call its accept method to let it wait for the incoming link request. This method returns only when a request is received, and it returns an instance of the Socket class. This socket object can be used to send and receive byte streams from the client application, as was said in the previous section. In fact, the Accept method is the only way to use this example.

Application examples

Our Web server program is part of a Ex01.pyrmont package that contains three classes: Httpserver; Request; Response.

The entry for the entire program (static Main method) is the Httpserver class. It creates an instance of Httpserver and calls its await method. As the name expresses, await waits for HTTP requests on a particular port, processes them, and returns the response to the client. It remains waiting until the Stop command is received. (Replace wait with method name await because there is an important thread-related method in System)

This program sends static resources, such as HTML and image files, from a specific directory. It only supports situations where there is no file header (such as Date and cookie). Now we'll look at these three classes in the following sections.

Httpserver class

Httpserver implements a Web server that can provide (serve) static resources under a specific directory and its subdirectories. This particular directory is specified by the public static final web_root.

Web_root initialization is as follows:

public static final String Web_root =
System.getproperty ("User.dir") + File.separator + "Webroot";


The code list contains a directory called Webroot, which has some static resources that you can use to test the application. You can also see a servlet, which will be used in my next article: "How the Servlets container works".

In order to request a static resource, enter the address bar of the browser as address: http://machinename:port/staticResources

If you send a request from a different machine to a machine running this application, MachineName is the machine name or IP address that runs the application machine, port is 8080, staticresources is the requested file name, and it must be included in the Web_root directory.

For example, if you use the same computer to test this application, you want to httpserver send index.html this file, with the following address: http://localhost:8080/index.html

To stop the service, you only need to send a stop (shutdown) command from the browser, that is, after entering the Host:port field in the browser's address bar, plus a predefined string. In our Httpserver class, the Stop command is defined as SHUTDOWN, a static final variable.

private static final String Shutdown_command = "/shutdown";


So to stop the service, you can do this: Http://localhost:8080/SHUTDOWN

Now, let's take a look at the await method given in Listing 1.1. This code will be explained later in the code list.

Listing 1.1. The Httpserver class ' await method

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 starts with creating a ServerSocket instance and then enters a while loop.

ServerSocket = new ServerSocket (
Port, 1, Inetaddress.getbyname ("127.0.0.1"));
...
Loop waiting for a request
while (!shutdown) {
...
}


In the code in the while loop, the Accept method that runs to ServerSocket stops. This method returns only if the HTTP request is received on port 8080:

Socket = Serversocket.accept ();


After the request is received, the await method waits for Java.io.InputStream and Java.io.OutputStream from the Socket instance returned by the Accept method:

input = Socket.getinputstream ();
Output = Socket.getoutputstream ();


The await method then creates a request object and calls its parse method to parse the original HTTP request:

Create Request object and parse
Request Request = new request (input);
Request.parse ();


Next, the await method creates a Response object and sets it to the Request object, calling its Sendstaticresource method:

Create Response Object
Response Response = new Response (output);
Response.setrequest (Request);
Response.sendstaticresource ();


Finally, the await method closes the Socket and calls the request's GetURI method to check whether the address of the HTTP request is a stop command. If it is, the shutdown variable is set to True and the program exits the while loop:

Close the socket
Socket.close ();
Check if the previous URI is a shutdown command
shutdown = Request.geturi (). Equals (Shutdown_command);




Java-based Web server working principle 3
Author: Fajaven Dispatch time: 2003.09.12 17:11:54

Request class

The request class corresponds to HTTP requests. Creates an instance of this class and passes it to the InputStream object it obtains from the Socket, capturing communication with the client. The original data for the HTTP request can be obtained by calling one of the read methods of the InputStream object.

The Request class has two public methods parse and GetURI. The parse method resolves the original data of an HTTP request. It does not do much-the only thing that makes it effective is the URI of the HTTP request, which is obtained by calling the private method Parseuri. The Parseuri method takes a URI as a variable. Call the GetURI method to get the URI of the HTTP request.

To understand the workings of parse and Parseuri, you need to know the structure of the HTTP request, defined by RFC2616.

An HTTP request consists of three parts: request Line;headers;message body.

Now we just need to focus on the first part of the HTTP request--the request line. The request line begins with a method token, followed by the requested URI and protocol version, ending with a carriage return line break. The elements of the request line are separated by spaces. For example, a request line for a index.html file using the Get method is as follows:


Get/index.html http/1.1




The parse method passes the inputstream of the socket to the Request object to read the byte stream, and the array of bytes is buffered. It then places the bytes in the buffer byte array into the StringBuffer object called request, and replaces the StringBuffer with a String passed to the Parseuri method.

The code for the parse method is shown in Listing 1.2

Listing 1.2. The Request class ' Parse method


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 ());
}


The Parseuri method finds the first and second spaces of the request line, thereby obtaining the URI from the request line. Listing 1.3 shows the code for the Parseuri method.

Listing 1.3. The Request class ' Parseuri method

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;
}


Response class

The Response class describes the HTTP response. Its build method accepts the OutputStream object, as follows:

Public Response (OutputStream output) {
This.output = output;
}


The Response object is created by passing the await method of the OutputStream object obtained from the socket to the Httpserver class.

The Response class has two public methods Setrequest and Setstaticresource. Setrequest is used to pass the Request object to the Response object. It's simpler, and the code looks like listing 1.4:

Listing 1.4. The Response class ' Setrequest method

public void Setrequest (Request request) {
This.request = Request;
}


The Sendstaticresource method is used to send static resources, such as HTML files. Its implementation is shown in Listing 1.5:

Listing 1.5. The Response class ' Sendstaticresource method

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 ();
}
}


The Sendstaticresource method is very simple. It first instantiates the Java.io.File class by passing the parent-child directory to the build method of the File class.

File File New file (Httpserver.web_root, Request.geturi ());


Then check to see if the file exists. If present, the Sendstaticresource method passes the File object to create the Java.io.FileInputStream object. The FileInputStream read method is then invoked, and the byte array is written to the OutputStream object output. In this way, the contents of the static resource are sent to the browser as raw data.

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);
}
}


If the file does not exist, Sendstaticresource sends an error message to the browser.

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 ());


Compiling and running the application

To edit and run the application of this article, first you need to extract the source code zip file. The directly extracted directory is called the working directory, which has three subdirectories: src/,classes/,lib/. To compile the application, enter the following command from the working directory:

Javac-d. Src/ex01/pyrmont/*.java


The-D option writes the results to the current directory, not the src/directory.

To run the application, enter the following command in the current working directory:

Java ex01.pyrmont.HttpServer


Test this application, open your browser, and enter the address in the Address bar as follows: http://localhost:8080/index.html

You will see index.html in your browser, as shown in Figure 1.



Figure 1:web Output display of the server

In the console, you see the following:

Get/index.html http/1.1
Accept: */*
Accept-language:en-us
Accept-encoding:gzip, deflate
user-agent:mozilla/4.0 (compatible; MSIE 4.01; Windows 98)
host:localhost:8080
Connection:keep-alive

Get/images/logo.gif http/1.1
Accept: */*
Referer:http://localhost:8080/index.html
Accept-language:en-us
Accept-encoding:gzip, deflate
user-agent:mozilla/4.0 (compatible; MSIE 4.01; Windows 98)
host:localhost:8080
Connection:keep-alive


Summarize

In this article (divided into three parts), you see how a simple Web server works. The related application of this article includes only three classes, the function is not comprehensive. However, it is still a good learning tool.



Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.