Es bien sabido que la comunicación entre un servidor web y un cliente usa el protocolo HTTP. HTTP es un estándar para las solicitudes y respuestas del cliente y el servidor (TCP). Debido a que el protocolo HTTP se basa en el protocolo TCP, usaré Socket en Java para completar este servidor web simple. Para obtener información HTTP más detallada, puede consultar la información relevante para aprender sobre ella.
Antes de escribir el servidor, echemos un vistazo a las reglas de comunicación entre el navegador y el servidor.
En primer lugar, usamos Serversocket para simular un servidor, acceder a él a través del navegador y ver el contenido solicitado por el navegador:
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 test* * @author Jianggujin * */public class hqhttpproTocoltest {@test public void Server () lanza excepción {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); }}}Ejecutarlo con Junit y acceder a él a través del navegador: http://127.0.0.1 , podemos ver que la salida de contenido de solicitud del navegador en la consola es el siguiente:
GET / HTTP/1.1Host: 127.0.0.1Connection: keep-aliveAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36accept-coding: GZIP, Deflate, SDCHACECT-Languaje: ZH-CN, ZH; Q = 0.8
Para analizar mejor el contenido de la solicitud, escribimos una página HTML para enviar algunos datos y ver el contenido de la solicitud nuevamente:
<! Doctype html> <html> <fead> <meta charset = "utf-8"> <title> test </title> </head> <body> <form método = "post" action = "http://127.0.0.1?test=123"> <input type = "text" name = "name"/> <input " type = "enviar"/> </form> </body> </html>
Ingrese a Bob en el cuadro de entrada, haga clic en el botón para enviar y observe la salida de la consola:
Post/? Test = 123 http/1.1host: 127.0.0.1Connection: keep-aliveContent-length: 8cache-confuntrol: max-edad = 0accept: text/html, aplicación/xhtml+xml, aplicación/xml; q = 0.9, image/webp,*/*; q = 0.8origin: nulluser-a (Windows NT 5.1) AppleWebkit/537.36 (khtml, como gecko) Chrome/31.0.1650.63 Safari/537.36Content-type: Application/X-WWW-Form-URLENCODEDACT-ECODING: GZIP, Deflate, Sdchacept-Vanguage: ZH-CN, ZH;
Analicemos el contenido de esta solicitud:
La primera línea: consta de tres partes, separadas por espacios en el medio, la primera parte es el método de solicitud (get, post), la segunda parte son la ruta de solicitud y los parámetros de consulta, y la tercera parte es la versión del protocolo HTTP (HTTP/1.1)
Línea 2 a la línea 10: La información del encabezado de la solicitud, se pasa el nombre y el valor del encabezado de solicitud: Separe la línea undécima: Línea vacía 12th Línea: Contenido de formulario enviado, podemos obtener la siguiente conclusión: El primer comportamiento de la información de solicitud es el método de solicitud, la ruta de solicitud, los parámetros de consulta y la versión del protocolo HTTP. Después de la ruptura de la línea /R /N, la información del encabezado de solicitud es seguida inmediatamente por el descanso de la línea /R /N, la información del encabezado de solicitud es seguida por una línea en blanco después de que se complete la información del encabezado de solicitud, y los datos de la solicitud son seguidos inmediatamente por una línea en blanco. Cabe señalar que esto solo se simula. En cuanto a los envíos de archivos complejos, etc., no se discute aquí, y el formato de contenido de solicitud es ligeramente diferente.
En este punto, ya hemos conocido el contenido solicitado por el cliente. Echemos un vistazo al formato de los datos de respuesta del servidor después de recibir la solicitud. Creamos un nuevo proyecto web para probar y editar el contenido de la página HTML de la siguiente manera:
<! Doctype html> <html> <head> <meta charset = "utf-8"> <title> test </title> </head> <body> Esta es la página de prueba. </body> </html>
Inicie el servidor, luego escriba el código de prueba del cliente para obtener los datos de devolución del servidor:
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 test * * @author jianguggujin * */public class hqhtpProtprotprotprotprotprotprotprotprotprotprotprotprotprotprotprotprotprotprotprotprotprotprotep Server () lanza la excepción {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 () lanza la excepción {socket socket = new Socket ("127.0.0.1", 80); BufferedWriter Writer = new BufferedWriter (nuevo OutputStreamWriter (Socket.getOutputStream ())); Writer.Write ("get /servlet/test.html http/1.1/r/n"); Writer.Write ("Anfitrión: 127.0.0.1/r/n"); Writer.Write ("Conexión: Keep-Alive/R/N"); Writer.Write ("Aceptar: Text/Html, Application/XHTML+XML, Aplicación/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, como gecko) Chrome/31.0.1650.63 safari/537.36/r/n"); Writer.write ("Aceptar-Engoding: GZIP, Desflate, SDCH/R/N"); Writer.write ("Aceptar-Language: Zh-Cn, Zh; Q = 0.8/R/N"); escritor.write ("/r/n"); escritor.flush (); InputStream stream = Socket.getInputStream (); int r = -1; while ((r = stream.read ())! = -1) {system.out.print ((char) r); }}}Ejecutar el programa para obtener el servidor Devuelve el siguiente contenido:
Http/1.1 200 okserver: apache-coyote/1.1accept-ranges: bytesetag: w/"129-1456125361109" Último modificado: lunes, 22 de febrero de 2016 07:16:01 gmtcontent-type: texto/htmlcontent-longitud: 129date: lun, 22 FeB 2016 08:32 Gmt <! Doctype html> <html> <head> <fead> <meta charset = "utf-8"> <title> test </title> </head> <body> Esta es la página de prueba. </body> </html>
Del mismo modo, analicemos este mensaje de retorno:
La primera línea consta de tres partes, separadas por espacios en el medio, la primera parte es la versión del protocolo HTTP (http/1.1), la segunda parte es el código de estado de respuesta, y la tercera parte es la descripción de estado de respuesta de la segunda línea a la séptima línea, la información del encabezado de respuesta se transmite entre el nombre del encabezado de respuesta y el valor separado: separar la línea en octava: la línea novena al final de la línea de fines de la respuesta. Lo primero es la versión del protocolo HTTP de solicitud de solicitud, el código de estado de respuesta y la descripción del estado de respuesta, y la información del encabezado de respuesta es seguida por el descanso de la línea /r /n de la línea de respuesta, y la información del encabezado de respuesta es aprobada por el descanso de la línea /R /N, y la información del encabezado de respuesta es seguida por una línea en blanco después de que se completa la información del encabezado de respuesta, y los datos de respuesta son seguidos inmediatamente por los datos de respuesta. Cabe señalar que, además de esta respuesta, en realidad hay otros métodos correspondientes, como el fragmento, que no se discute aquí, y puede verificar la información relevante.
Hasta ahora, hemos analizado el formato de contenido de solicitud del cliente y el formato de contenido correspondiente del servidor. Este artículo termina aquí. Espero que sea útil para el aprendizaje de todos.