Java-based web server implementation [Z]

xiaoxiao2021-03-06  39

Java-based web server working principle 1 One web server is also known as HTTP server, which communicates with client via HTTP protocol. This client usually refers to a web browser. A Java-based web server uses two important classes, java.net.socket with java.net.serversocket, and communicates with HTTP messages. Therefore, this article starts from the discussion of HTTP and this two classes, and then I will explain a simple web application related to this article. The Hypertext Transfer Protocol (HTTP) HTTP is a protocol that allows web servers and browsers (clients) to send and receive data through Internet. It is a request, a response protocol-client issues a request, the server responds to this request. HTTP uses reliable TCP connections, usually used TCP 80 ports. 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 make you fully understand the message issued by the web server program. 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 with an HTTP request. The server can't actively contact the client, and you cannot give a callback connection to the client. The client can interrupt one connection in advance and the server side. For example, when you download a file with a browser, you can interrupt the file by clicking the "Stop" button, turn off the HTTP connection with the server. HTTP requests an HTTP request contains three parts: method-uri-protocol / version method - Address - version Request Header Request Head Entity Body Request Entity Below is an HTTP Request Instant: Post / Servlet/default.jsp HTTP / 1.1ACCEPT: Text / plain; text / html Accept-Language: en-gb Connection: Keep-Alive Host: localhost Referer: http: //localhost/ch8/SendDetails.htmUser-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 in 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 requested types specified in the HTTP specification. HTTP 1.1 supports seven types of requests, which are Get, Post, Head, Options, Put, Delete, Trace. Where GET and POST are the types that are often used in the Internet application. The URI specifies the Internet resource. A URI is usually parsed to the root directory of the relative server. This should always start with a '/' prefix. A URL is actually a type of URI. Version refers to the HTTP protocol version used by the HTTP request.

The request header contains some useful information for the client environment and the request entity. For example, it contains the language set by the browser, the length of the entity, and the like. Each request header is separated by the carriage return line (CRLF). A very important air line separates the request head and the entity, which marks the beginning of the entity content. Some Internet development books believe that this CRLF space line is the fourth part of the HTTP request. In the above HTTP request, the entity is just a row of the following: LastName = FRANKS & FIRSTNAME = Michael In a typical HTTP request, the request entity is much longer. HTTP response is similar to the request, HTTP response is also composed of three parts: Protocol-status code-description protocol status Description Code Response Headers Response Head Entity Body Response Entity The following is an instance of an HTTP response: http / 1.1 200 okserver: Microsoft-IIS / 4.0Date: MON, 3 Jan 1998 13:13:33 Gmtcontent-Type: TEXT / HTMLLAST-Modified: Mon, 11 Jan 1998 13:23:42 Gmtcontent-Length: 112 http response eXample </ title> </ head> <body> Welcome To Brainy Software </ body> </ html> Responding to the first line of the head like the first line of the requested head, telling the protocol used by HTTP 1.1, request success (200 = Success), and there is no problem. Respond to the head similar to the request head also contains some useful information. The responding entity responds to the HTML content itself. The head and the entity are separated by the empty line (CRLF) of the carriage return. Socket class A socket is an endpoint of a network connection, which makes an app to read from the network. Two applications on different computers can communicate with each other by sending and receives. To send an information 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 the host names and port numbers as parameters: New socket ("Yahoo.com", 80); Once you have successfully created an instance of a Socket class, you can use it to send and receive byhal. To send a byte stream, you need to call the GetoutPutStream method for the Socket class to get a java.io.outputsteam object. To send text to remote programs, you usually need to create a java.io.printwriter object from the return of 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 that can communicate with the local HTTP server (127.0.0.1 represents a local host), sends an HTTP request and receives the response from the server. It also creates a StringBuffer object to accept the response and print it to the console.</p> <p>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 (socket.getinputStream ())); // send an http request to the web serverout.println ("get /index.jsp http / 1.1"); Out.Println ("Host: localhost: 8080) Out.println ("Connection: Close"); OUT.Println (); // read the responseboolean 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 consolesystem.out.println (sb.tostring ()); socket.close (); Note To get the correct response from the web server, you must send HTTP requests 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 Note: This article is selected from the book <Tomcat insider> of Budi. You can get more information on his website. Java-based Web server works 2 Author: fajaven issued a document translation time: 2003.09.12 17:00:38 ServerSocket class Socket class described as "client" socket, when you need to create a connection with the remote service program need to use it . If you want to implement a service, such as an HTTP server or FTP server, there is a different method. This is because your server must wait any time, it doesn't know when there will be a client program to need to connect it. Because of this purpose, you need to use the java.net.serversocket class, which is an implementation of the server side socket. Server-side Socket Waizards a connection request from the client. Once it receives a connection request, it creates a socket instance to communicate with the client. To create server-side socket, you need to use one of the four build methods provided by the ServerSocket class. You need to specify the IP address and port number of the server-side Socket listening. More typically, this IP address can be 127.0.0.1, meaning that the server side Socket is listening to the local machine. The IP address of the server-side socket listening is the binding address. The other important attribute of the server side Socket is the queue length, that is, it refuses to request the maximum requested queue length accepted before the request.</p> <p>One of the build methods for the Serversocket class: Public ServerSocket (INT Port, INT Backlog, InetDress BindingAddress); For this build method, the binding address must be an instance of the Java.Net.Netaddress class. A simple way to create an object of an inetaddress class is to call its static method getByname to pass a string containing the host name. Inetaddress.getbyName ("127.0.0.1"); The following line of code creates a server-side socket that listens to the 8080 port of the local machine, and the limit queue length is 1. New ServerSocket (8080, 1, inetaddress.getbyname); once there is a ServerSocket instance, you can wait for the link request to come in by calling its Accept method. This method only returns when the 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 the above is said. In fact, the Accept method is the only way to use in this example. Application Example Our web server program is part of the EX01.PYRMont package, which contains three classes: httpserver; request; response. The entrance (static main method) of the entire program is an HTTPSERVER class. It creates an instance of HTTPServer and calls its AWAIT method. As the name is expressed, AWAIT waits for HTTP requests on a specific port, and the response should be returned to the client. It keeps the waiting state until the stop command is received. (With the method name AWAIT instead of Wait because there is an important way in SYSTEM) This program only sends static resources from a specific directory, such as HTML and image files. It only supports the case where there is no file header (such as date and cookie). Now we will look at these three classes in the following sections. The HTTPServer class HTTPServer implements a web server that provides static resources in a specific directory and its subdirectory. This specific directory is specified by Public Static Final Web_root. Web_root initializes the following: public static final string Web_root = system.getProperty ("user.dir") file.seParetor "Webroot"; the code list contains a directory called Webroot, there are some static resources, you can Used to test this application. You can also see a servlet, in my next article, will be used: "How the servlets container works". In order to request a static resource, enter the address bar of the browser, such as the address: http: // MachineName: Port / StaticResources If you send a request to the machine from different machines to run this app, MachineName is a machine running the application machine. Name or IP address, Port is 8080, StaticResources is the requested file name, which must be included in the web_root directory.</p> <p>For example, if you use the same computer to test this app, you want httpserver to send index.html file, with the following address: http: // localhost: 8080 / index.html To stop the service, only need to send from the browser A shutdown command, that is, after entering the Host: Port field in the address bar of the browser, add 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"; therefore, to stop the service, you can do this: http: // localhost: 8080 / shutdown now, let's take a look at the AWAIT method given in the list 1.1. The code list will be explained to this code. . 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 requestwhile (shutdown!) {Socket socket = null; InputStream input = null; OutputStream output = null; try {socket = serverSocket.accept (); input = socket.getInputStream (); output = socket.getOutputStream (); // create Request object and parseRequest request = new Request (input); request.parse (); // create Response objectResponse response = new Response (output); response.setRequest (request); response.sendStaticResource (); // Close the socketsocket.close (); // check if the previous URI is a shutdown commandshutdown = request.getUri () equals (SHUTDOWN_COMMAND. );} catch (Exception E) {E.PrintStackTrace (); Continue;}}} AWAIT method to create a ServerSocket instance, then enter a while loop. Serversocket = New Serversocket (port, 1, inetaddress.getbyname ("127.0.0.1"))); ... // loop wait for a requestWhile (! shutdown) {...} On the WHILE loop, run to Serversocket The Accept method is stopped.</p> <p>This method only returns to the 8080 port to receive HTTP requests: socket = serversocket.accept (); After receiving the request, the AWAIT method returned from the Socket instance returned from the Accept method to java.io.inputstream and java.io.outputStream: Input = socket.getInputStream (); output = socket.getOutputStream (); then await method creates a request object, it calls the method to resolve the original parse HTTP request: // create request object and parseRequest request = new request (input) Request.Parse (); Next, the AWAIT method creates a response object and sets the Request object to it, calls its SendStaticResource method: // Create response ObjectResponse response = new response (output); response.setRequest (request); Response.sendStaticResource (); Finally, the AWAIT method closes the socket, call the request's geturi method to check if the address of the HTTP request is a stop command. If so, the shutdown variable is set to true, the program exits while loop: // close the socketsocket.close (); // check if the previous URI is a shutdown commandshutdown = request.geturi (). Equals (shutdown_command); Java Web server works 3 author: fajaven dispatch time: 2003.09.12 17:11:54 request class request class corresponding to the HTTP request. Create this class instance and pass it from the INPUTSTREAM object obtained from Socket to capture communication with the client. The original data of the HTTP request can be obtained in the Read method of the call InputStream object. The REQUEST class has two public methods Parse with geturi. PARSE method parses the original data of the HTTP request. It doesn't have much thing - the only information it makes effective is the URI of the HTTP request, which is obtained by calling private method Parseuri. Parseuri method puts the URI as a variable. Call the geturi method to get the URI requesting HTTP request. To understand the working principle of PARSE and PARSEURI, you need to know the structure of the HTTP request, defined by the RFC2616. An HTTP request consists of three parts: Request line; Headers; Message Body. Now, we only need to pay attention to the first part of the HTTP request - request row. The request row starts with methodology, followed by the requested URI and protocol version, and the return line end. The requested line is separated between spaces.</p> <p>For example, a request routine with a GET method's index.html file is as follows: Get /index.html http / 1.1 Parse method passed from Socket's InputStream to the Request object reads the byte stream, put this byte array There is a buffer. It then puts the byte in the buffer byte array into the StringBuffer object called Request, and then replaces StringBuffer to String to the Parseuri method. The method as parse the code list 1.2 Listing 1.2 The Request class' parse method  public void parse () {// Read a set of characters from the socketStringBuffer 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 ());} Parseuri method Find the first one with the request Two spaces are obtained from the request line. Listing 1.3 shows the code of the Parseuri method. . Listing 1.3 The Request class' parseUri method private String parseUri (String requestString) {int index1, index2; index1 = requestString.indexOf ( ''); if (-1 index1 =!) {Index2 = requestString.indexOf ( '', Index1 1); if (Index2> index1) Return RequestString.Substring (INDEX1 1, INDEX2);} Return Null;} The HTTP response is descriptated. Its build method accepts the OutputStream object, as follows: public response (OutputStream output) {this.output = Output;} Response object is created by passing the OutputStream object obtained from the socket to the AWAIT method of the HTTPServer class. The Response class has two public methods setRequest with setStaticResource. SetRequest is used to pass the Request object to the Response object. It is relatively simple, the code is shown in list 1.4: listing 1.4. The response class' setRequest method (this.Request = request;} sendstaticResource method is used to send static resources, such as HTML files.</p> <p>Its implementation 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 ()) {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 foundstring 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>"; OUTPUT.WRITE ErrorMessage.getBytes ());}} catch (Exception E) {// thrown if cannot instantiate a file objectsystem.out.println (E.TOString ());} finally {if (fis! = null) fis.close )}} The SendStaticResource method is very simple. It first instantizes the Java.IO.File class by transmitting the build method of the Fi and the subdirectory to the File class. File file new file (httpserver.web_root, request.geturi ()); then check if this file exists. If there is, the SendStaticResource method passes the File object to create a java.io.fileInputStream object. Then call the FileInputStream read method and write the byte array to the OutputStream object Output. In this way, the content of the static resource is sent to the browser as the original data. IF (file.exists ()) {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.</p></div><div class="text-center mt-3 text-grey"> 转载请注明原文地址:https://www.9cbs.com/read-77258.html</div><div class="plugin d-flex justify-content-center mt-3"></div><hr><div class="row"><div class="col-lg-12 text-muted mt-2"><i class="icon-tags mr-2"></i><span class="badge border border-secondary mr-2"><h2 class="h6 mb-0 small"><a class="text-secondary" href="tag-2.html">9cbs</a></h2></span></div></div></div></div><div class="card card-postlist border-white shadow"><div class="card-body"><div class="card-title"><div class="d-flex justify-content-between"><div><b>New Post</b>(<span class="posts">0</span>) </div><div></div></div></div><ul class="postlist list-unstyled"> </ul></div></div><div class="d-none threadlist"><input type="checkbox" name="modtid" value="77258" checked /></div></div></div></div></div><footer class="text-muted small bg-dark py-4 mt-3" id="footer"><div class="container"><div class="row"><div class="col">CopyRight © 2020 All Rights Reserved </div><div class="col text-right">Processed: <b>0.045</b>, SQL: <b>9</b></div></div></div></footer><script src="./lang/en-us/lang.js?2.2.0"></script><script src="view/js/jquery.min.js?2.2.0"></script><script src="view/js/popper.min.js?2.2.0"></script><script src="view/js/bootstrap.min.js?2.2.0"></script><script src="view/js/xiuno.js?2.2.0"></script><script src="view/js/bootstrap-plugin.js?2.2.0"></script><script src="view/js/async.min.js?2.2.0"></script><script src="view/js/form.js?2.2.0"></script><script> var debug = DEBUG = 0; var url_rewrite_on = 1; var url_path = './'; var forumarr = {"1":"Tech"}; var fid = 1; var uid = 0; var gid = 0; xn.options.water_image_url = 'view/img/water-small.png'; </script><script src="view/js/wellcms.js?2.2.0"></script><a class="scroll-to-top rounded" href="javascript:void(0);"><i class="icon-angle-up"></i></a><a class="scroll-to-bottom rounded" href="javascript:void(0);" style="display: inline;"><i class="icon-angle-down"></i></a></body></html><script> var forum_url = 'list-1.html'; var safe_token = 'eDK4VhgWXkOVkWTVSvogjgqHgMwssg2WStZ93KOVwHdhYZ4BiYXtmrqmDZXgbDSaa5pXoiLK8rKQ8Kgs2Wh4Ew_3D_3D'; var body = $('body'); body.on('submit', '#form', function() { var jthis = $(this); var jsubmit = jthis.find('#submit'); jthis.reset(); jsubmit.button('loading'); var postdata = jthis.serializeObject(); $.xpost(jthis.attr('action'), postdata, function(code, message) { if(code == 0) { location.reload(); } else { $.alert(message); jsubmit.button('reset'); } }); return false; }); function resize_image() { var jmessagelist = $('div.message'); var first_width = jmessagelist.width(); jmessagelist.each(function() { var jdiv = $(this); var maxwidth = jdiv.attr('isfirst') ? first_width : jdiv.width(); var jmessage_width = Math.min(jdiv.width(), maxwidth); jdiv.find('img, embed, iframe, video').each(function() { var jimg = $(this); var img_width = this.org_width; var img_height = this.org_height; if(!img_width) { var img_width = jimg.attr('width'); var img_height = jimg.attr('height'); this.org_width = img_width; this.org_height = img_height; } if(img_width > jmessage_width) { if(this.tagName == 'IMG') { jimg.width(jmessage_width); jimg.css('height', 'auto'); jimg.css('cursor', 'pointer'); jimg.on('click', function() { }); } else { jimg.width(jmessage_width); var height = (img_height / img_width) * jimg.width(); jimg.height(height); } } }); }); } function resize_table() { $('div.message').each(function() { var jdiv = $(this); jdiv.find('table').addClass('table').wrap('<div class="table-responsive"></div>'); }); } $(function() { resize_image(); resize_table(); $(window).on('resize', resize_image); }); var jmessage = $('#message'); jmessage.on('focus', function() {if(jmessage.t) { clearTimeout(jmessage.t); jmessage.t = null; } jmessage.css('height', '6rem'); }); jmessage.on('blur', function() {jmessage.t = setTimeout(function() { jmessage.css('height', '2.5rem');}, 1000); }); $('#nav li[data-active="fid-1"]').addClass('active'); </script>