In the previous two articles, "GET Implementation of HTTP request packets" and "HTTP request packet Java Implementation" have explained the request connection content of the HTTP packet. This article will continue to provide some additional information to explain how to read the HTTP packet.
The following is a SocketRequest class designed by myself to read the HTTP protocol package 。
- Public class SocketRequest
- {// Read data from the InputStream of the specified Socket
- Private InputStreaminput;
- Private Stringuri;
- Private StringBufferrequest = new StringBuffer (); // used to save all content
- Private intCONTENT_LENGTH = 0; // The Data Length of the actual package content
- Private boolean bePost = false;
- Private boolean beHttpResponse = false;
- Private boolean beChucked = false;
- Private boolean beGet = false;
- Private bytecrlf13 = (byte) 13; // 'R'
- Private bytecrlf10 = (byte) 10; // 'n'
- Public SocketRequest (InputStream input ){
- This. input = input ;}
- Public SocketRequest (Socket socket ){
- This. input = socket. getInputStream ();}
- Public void ReadData ()
- {// Parse the InputStream data
- ReadHeader (); // Header
- If (beChucked) // It is Chucked
- {Int ChuckSize = 0;
- While (ChuckSize = getChuckSize ()> 0) // multiple Chucked
- {ReadLenData (ChuckSize + 2); // read the fixed-length data}
- ReadLenData (2); // the last two digits}
- If (CONTENT_LENGTH> 0)
- {ReadLenData (CONTENT_LENGTH); // read the fixed-length data}
- Uri = ""; // parseUri (new String (request ));}
- Private void readLenData (int size) // read the fixed-length data
- {Int readed = 0; // read count
- Try {
- Int available = 0; // input. available (); // readable
- If (available> (size-readed) available = size-readed;
- While (readed <size)
- {While (available = 0) {// wait until data is readable
- Available = input. available (); // readable}
- If (available> (size-readed) available = size-readed; // size-readed -- remaining number
- If (available> 2048) available = 2048; // size-readed -- remaining number
- Byte [] buffer = new byte [available];
- Int reading = input. read (buffer );
- Request = request. append (new String (buffer, 0, reading); // Add byte Arrays
- Readed + = reading; // read characters
- } Catch (IOException e) {System. out. println ("Read readLenData Error! ");}}
- Private voidReadHeader () // read the header and obtain the size
- {Byte [] crlf = new byte [1];
- IntcrlfNum = 0; // The number of line breaks connected to the carriage return. crlfNum = 4 indicates the end of the header.
- Try {while (input. read (crlf )! =-1) // read the header
- {If (crlf [0] = crlf13 | crlf [0] = crlf10)
- {CrlfNum ++ ;}
- Else
- {CrlfNum = 0;} // clear if not
- Request = request. append (new String (crlf,); // Add the byte array
- If (crlfNum = 4) break ;}}
- Catch (IOException e) {System. out. println ("Read Http Header Error! ");
- Return ;}
- String tempStr = (new String (request). toUpperCase (); // here I only process the GET and POST Methods
- StringstrMethod = tempStr. substring (0, 4 );
- If (strMethod. equals ("GET") // before
- {BeGet = true ;}
- Else if (strMethod. equals ("POST "))
- {BePost = true;
- GetContentlen_Chucked (tempStr );}
- Else {System. out. println ("unsupported HTTP packet type");} // other types are not currently supported
- }
- Private void getContentlen_Chucked (String tempStr) // obtain the CONTENT-LENGTH or whether it is CHUNKED
- {String ss1 = "CONTENT-LENGTH :";
- String ss2 = new String ("TRANSFER-ENCODING: CHUNKED ");
- Int clIndex = tempStr. indexOf (ss1 );
- Int chuckIndex = tempStr. indexOf (ss2); // CHUNKED type
- Byte requst [] = tempStr. getBytes ();
- If (clIndex! =-1)
- {// Starting from clIndex + 1 to rn
- StringBuffer sb = new StringBuffer ();
- For (int I = (clIndex + 16); I ++)
- {If (requst [I]! = (Byte) 13 & requst [I]! = (Byte) 10)
- {Sb. append (char) requst [I]);}
- Else
- Break ;}
- CONTENT_LENGTH = Integer. parseInt (sb. toString (); // the size of the formal HTML file
- // System. out. println ("CONTENT_LENGTH =" + CONTENT_LENGTH );}
- If (chuckIndex! =-1) beChucked = true ;}
- Private intgetChuckSize () // Chuck size {
- Byte [] crlf = new byte [1];
- StringBuffersb1 = new StringBuffer ();
- IntcrlfNum = 0; // The number of line breaks connected to the carriage return. crlfNum = 4 indicates the end of the header.
- Try {while (input. read (crlf )! =-1) // read the header {
- If (crlf [0] = crlf13 | crlf [0] = crlf10)
- {CrlfNum ++ ;}
- Else
- {CrlfNum = 0;} // clear if not
- Sb1.append (char) crlf [0]);
- Request = request. append (new String (crlf,); // Add the byte array
- If (crlfNum = 2) break ;}
- } Catch (IOException e ){
- System. out. println ("Read Http Package Error! ");
- Return 0 ;}
- Return Integer. parseInt (sb1.toString (). trim (), 16); // 16.
- } // Use this method to filter whether the HTTP protocol package is sent to the target server
- 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 ;}
- Public String getData (){
- Return request. toString ();}}
Use this class:
- SocketRequest request = new SocketRequest (socket); // The socket is the Socket instance returned by ServerSocket. accept ().
- Request. ReadData (); // read data
- Request. getData ();
Why should I use this powerful power to read data? Especially when the Socket connection sends data, latency often occurs due to network reasons, when the server starts receiving data, it is possible that only part of the data can be obtained from InputStream. Otherwise, incomplete data or incorrect data may be obtained 。
There are multiple methods to read bytes from InputStream:
Commonly used int read () and int read (byte [] B). When read (byte []) is used, programmers often make mistakes because in the network environment, the amount of data read is not necessarily equal to the size of the parameter 。