Implement HTTP Protocol Client Apply with Socket Class
Liang Yingjian liangyingjian@21cn.com
The HTTP client program is integrated in the Java language, which can be called via the URLConnection class. Unfortunately, because Sun does not publish the source code of the HTTP client, the details of its implementation are still a mystery. This article implements an HTTP protocol client program in accordance with the Java.Net.Socket class in accordance with the HTTP protocol specification. 1. Socket class: Understand the readers of the TCP / IP protocol set communication, communication between the protocols is done through socket. In a java.net package, the Socket class is the specific implementation of Socket. After connecting to the host, it returns an I / O stream to implement information exchange between protocols. 2. The HTTP protocol The HTTP protocol is the same as the protocol in other TCP / IP protocols, which follows the client / server model. The information format of the client is as follows: ----------------------------- Request method URL HTTP protocol version number submitted Met information ** blank line ** entity ---------------------------- request method is a description of this connection work, At present, the HTTP protocol has also developed to version 1.1, including GET, HEAD, POST, DELETE, OPTIONS, TRACE, PUT seven. The meta information is information about the current request. Through analysis element information, you can check if the entity data is complete, whether the receiving process is wrong, whether the type matches the same. The introduction of meta information makes HTTP protocol communications more secure. The entity is the specific content of the request. Send the above message to the web server, if successful, the answer format is as follows: ------------------------------ HTTP protocol Version number response status code response status code Description received meta information ** blank ** entity ----------------------------- --- The above newspaper is sent to the client, and the reception is successful, and the connection is turned off at each other, and the handshake is completed. The following uses the most common GET method to clear the specific packet application ------------------------------ Get http://www.youhost.com http / 1.0accept: www / source; text / html; image / gif; image / jpeg; * / * user_agent: myagent ** blank ** ---------- -------------------------- this message is to request a default HTML document to www.youhost.com host. The client HTTP protocol version number is version 1.0, and the metadet information includes the received file format, the user agent, and each segment is separated by the carriage return line, and finally ends with an idlore. After the server is sent, if the execution process is normal, the server returns the following code: --------------------------------- -HTTP / 1.1 200 Okdate: Tue, 14 Sep 1999 02:19:57 GMTSERVER: APACHE / 1.2.6Connection: CloseContent-Type: Text / HTML ** Space **
... head > ... body> html> --------------------------------- -HTTP / 1.1 indicates that this HTTP server is version 1.1, 200 is the reply status code requested by the server to the client, and OK is an explanation of the reputation status code, which is then the metadet information and document body. (Explanation of related response status codes and meta information, please refer to the INETRNET standard draft: RFC2616).3. HTTP client program: import java.net *; import java.io *; import java.util.Properties; import java.util.Enumeration; public class Http {protected Socket client; protected BufferedOutputStream sender; protected BufferedInputStream receiver.. ; protected ByteArrayInputStream byteStream; protected URL target; private int responseCode = -1; private String responseMessage = ""; private String serverVersion = ""; private Properties header = new Properties (); public Http () {} public Http (String url ) {GET (URL);} / * GET method According to the URL, the file, database query results, program operation results, and more * / public void get (url) {Try {checkhttp (url); OpenServer .gethost (), target (); string cmd = "get" getURLFormat "http / 1.0 / r / n" getBaseheads () "/ r / n"; sendMessage (cmd); receiveMessage ();} catch (ProtocolException p) {p.printStackTrace (); return;} catch (UnknownHostException e) {e.printStackTrace (); return;} catch (IOException i) i.printStackTrace (); return;}} / ** HEAD method only requests meta information of the URL, does not include the URL itself. If you doubt the * file on the server, you check the fastest and more effective with this method. * / public void head (string URL) {try {checkhttp (url); OpenServer (), target.getport (); string cmd = "head" getURLFormat (Target) "http / 1.0 / r / N " getBaseheads () " / r / n "; sendMessage (); ReceiveMessage ();} catch (protocolexception p) {p.PrintStackTrace (); return;} catch (unknownhostException e) {E.PrintStackTrace ( );}} catch (ooException i) I.PrintStackTrace (); return;}} / ** Post method is to transmit data to the server so that the server makes corresponding processing. For example, web pages are commonly used * Submit form.
* / public void post (string url, string content) {Try {checkhttp (url); OpenServer (), target.getport (); string cmd = "post" getURLFormat "http / 1.0 / r / n " getBaseheads (); cmd =" Content-type: application / x-www-form-urlencoded / r / n "; cmd =" Content-length: " Content.Length () "/ r / n / r / n"; cmd = content "/ r / n"; sendMessage (); ReceiveMessage ();} catch (protocolexception p) {p.PrintStackTrace (); return;} catch (unknownhostException e) {e.printStackTrace (); return;} catch (IOException i) i.printStackTrace (); return;}} protected void checkHTTP (String url) throws ProtocolException {try {URL target = new URL (url); if ( TARGET == NULL ||! target.getProtocol (). TouPpercase (). Equals ("http")) Throw new protocolexception ("this is not HTTP protocol"); this.target = target;} catch (mALFORMEDURLEXCEPTION M) {throw NEW Protocolexception ("Protocol Format Error");}} / ** Connect to the web server. If you can't find a web server, inetaddress will trigger unknownhostexception * exception. If the Socket connection fails, IOEXCEPTION exception will be triggered.
* / Protected void openServer (String host, int port) throwsUnknownHostException, IOException {header.clear (); responseMessage = ""; responseCode = -1; try {if (! Client = null) closeServer (); if (byteStream =! null) {byteStream.close (); byteStream = null;} InetAddress address = InetAddress.getByName (host); client = new Socket (address, port == - 1 80:? port); sender = new BufferedOutputStream (client.getOutputStream ()); receiver = new BufferedInputStream (client.getInputStream ());} catch (UnknownHostException u) {throw u;} catch (IOException i) {throw i;}} / * Close the connection to the Web server * / protected void CloseServer () THROWS IOEXCEPTION {IF (client == null) Return; try {client.close (); sender.close (); receiver.close ();} catch (ooException i) {throw i;} client = null; Sender = NULL; Receiver = NULL;} protected string geturlformat (url target) {string spec = "http: //" target.getHost (); if (Target.getPort ()! = - 1) Spec = ":" Target.get (); return spec = target.getfile ();} / * Transfer data to the web server * / protected void sendmessage (String Data) throws oException {sender.write Data.GetBytes (), 0, data.length ()); sender.flush ();} / * receive data from the web server * / protected void receiveMessage () throws ioException {byte data [] = new byte [1024] ; int count = 0; int Word = -1; // Analysis of the first bank while ((word = receiver.read ()))! = - 1) {if (word == '/ r' || Word == ' / n ') {word = receiver.read (); if (word ==' / n ') word = receiver.read (); break;} if (count == data.length) Data = AddCapacity (data); Data [count ] = (byte) word;} string message = new string (data, 0, count); int mark = message.indexof (32); serverversion = message.substring (0, mark); while (Mark <
message.length () && message.charAt (mark 1) == 32) mark ; responseCode = Integer.parseInt (message.substring (mark 1, mark = 4)); responseMessage = message.substring (mark, message. Length ()). trim (); // Answer status code and handle Reader Add Switch (ResponseCode) {Case 400: Throw New IOException ("Error Request"); Case 404: Throw New FilenotFoundException (GetURLFormat (Target); Case 503: Throw new oException ("server is not available");} if (word == - 1) throw new protocolexception ("Information Receive Exception Termination"); int symbol = -1; count = 0; // Analyze the meta information While (Word! = '/ R' && Word! = '/ n' && Word> -1) {if (word == '/ t') Word = 32; if (count == data.length) Data = addcapacity (DATA); DATA [Count ] = (Byte) Word; Parseline: {while ((Symbol = receiver.read ())> -1) {switch (Symbol) {CASE '/ T': Symbol = 32; Break; Case '/ r': case '/ n': word = receiver.read (); if (symbol == '/ r' && word == '/ n') {Word = received (); if (word == '/ r') word = receiver.read ();} if (word == '/ r' || Word == '/ n' || Word> 32) Break Parseline; Symbol = 32; Break;} IF (count == Data.Length) Data = addcapacity (data); data [count ] = (byte) Symbol;} word = -1;} message = New string (data, 0, count); mark = message.indexof (':'); string key = null; if (Mark> 0) Key = Message.Substring (0, Mark); Mark ; While (Mark