Socket input buffer Device--internalinputbuffer

Source: Internet
Author: User

The world of the Internet is very complex, the process of information from one end to the other is quite complex, the middle may pass through a number of hardware, in order to improve the transmission and reception efficiency, both at the sender and receiver will be introduced buffer, so both ends of the socket has its own buffer, of course, the introduction of this buffer has also brought an indeterminate delay On the sending side, the message is generally written to the buffer until the buffer fills up before sending, and the receiving side reads only the message up to the buffer size at a time.

Tomcat needs to read the client's request data while it is processing the client's request, and it also needs a buffer to receive the byte stream, the socket input buffer, whose primary responsibility is to provide a buffer mode to read the byte stream from the socket, provide a method to fill the buffer, and read the bytes to the buffer buf , provides methods for parsing HTTP protocol request lines, provides methods for parsing HTTP protocol request headers, and assembles request object requests according to the parsed results.

The socket input buffer does not work as complex, as shown in the Internalinputbuffer contains the following variables: byte array buf, Integer pos, integer lastvalid, Integer end. Where buf is used to store buffer byte stream, its size is set by the program, tomcat default is set to 8 * 1024, that is, 8k bytes; POS indicates the read pointer, which position value is read, and Lastvalid represents the last position in the BUF from the underlying reading data from the operating system. End represents the location of the end of the HTTP protocol request message header in the buffer buf, and also indicates the beginning of the style of the report.

From the top to the bottom, the first buffer buf is empty, the socket operating system underlying a number of bytes read into the buf, so the state as shown in ②, read the byte stream will buf from the back to fill, while the POS 0,lastvalid for this read the last position value, Then the second reading of the operating system underlying several byte stream, each read how much is not sure, the byte stream should be connected in ② lastvalid the specified location behind instead of starting from the beginning, at this point, POS and lastvalid according to the actual situation is given a new value, if read again the final state is ⑤, An end variable is given, which means the request line of the HTTP request message and the location of the end of the request header.

In order to better understand how to read the byte stream from the bottom and parse, the following will give a simplified process, first need a method to provide read byte stream, such as below, where InputStream represents the input stream of the socket, obtained through Socket.getinputstream (), Where the Read method is used to read a byte stream, which represents a byte stream that reads up to (buf.length-lastvalid) length from the underlying, and fills the stream into the BUF array, the start position of the fill is buf[pos], and the nread represents the number of bytes actually read. By manipulating the above variables, the buffer unit can be operated accurately, and the successful padding returns true.

Publicclass internalinputbuffer{

Byte[] buf=newbyte[8*1024];

int pos=0;

int lastvalid=0;

Public Booleanfill () {

int nread = Inputstream.read (Buf,pos, buf.length-lastvalid);

if (Nread >0) {

Lastvalid = pos + nread;

}

Return (nread> 0);

}

}

With the method of filling down requires a parsing of the operation of the message, the space affected by this only provides the method and path of the request line resolution as an example, the other resolution in accordance with similar operations. HTTP protocol Request message format, request line a total of three values need to parse out: Request method, request URL and protocol version, with a space interval and end with a carriage return newline character. The parsing method is as follows:


Publicboolean Parserequestline () {

int start = 0;

byte CHR = 0;

Boolean space = false;

while (!space) {

if (POS >= lastvalid)

Fill ();

if (buf[pos] = = (byte) ') {

Space = true;

byte[] MethodB = new Byte[pos-start];

System.arraycopy (buf, start,methodb,0, Pos-start);

String method = NewString (MethodB);

Request.setmethod (method);

}

pos++;

}

while (space) {

if (POS >= lastvalid)

Fill ();

if (buf[pos] = = (byte) ') {

pos++;

} else {

Space = false;

}

}

start = pos;

while (!space) {

if (POS >= lastvalid)

Fill ();

if (buf[pos] = = (byte) ') {

Space = true;

byte[] Urib = Newbyte[pos-start];

System.arraycopy (buf, Start,urib, 0, Pos-start);

String uri = new string (Urib);

Request.seturi (URI);

}

pos++;

}

return true;

}

The first while loop is used to parse the method name, and before each operation it is necessary to determine whether the byte stream needs to be read from the underlying, and when the POS is greater than or equal to Lastvalid, the Fill method is called to read, and when the byte equals the ASCII-encoded space, it intercepts the array of bytes from start to Pos They are the byte of the method name, which is set to the request object after the string object, and the second while loop is used to skip all the spaces between the method name and the URI, and the third while loop is used to parse the URI, which has the same logic as the previous method name resolution. The parsed URI is eventually set to the request object.

At this point, the whole working principle of the buffer device is basically clear, a complete process is from the underlying byte stream reading to the parsing of these byte stream and assembled into a request object to use after the application, because every time can not be guaranteed to read from the bottom of the byte stream, so through the POS, The lastvalid variable is controlled so that the exact read and receive of the byte stream is completed. In addition, the input buffer provides a way to parse the request header, which is parsed according to the HTTP protocol, and then put into the request object in turn. As an additional explanation, Tomcat does not actually run the request line, the request prime argument after parsing it into a string type set to request, but continue to use ASCII code to store these values, because transcoding these ASCII code can cause performance problems, Its idea is only to need to use when the transcoding, many parameters are not used to do not transcode, in order to improve processing performance. Detailed information on this is covered in the request section.

Socket input buffer Device--internalinputbuffer

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.