Toma 4.1 HTTP/1.1永続化処理(バイトストリームを行で読み出す)を実現
3864 ワード
1.ブラウザがデータを送信する場合、get方式であれば直接送信し、post方式であればcontent-lengthを送信して送信データのサイズを示す2.ブラウザはデータを受信する際に一般的に受信データのサイズを知っているが、このようにブラウザは盲目的に待機したりブロックしたりすることはありません.3.サーバは要求を読み取るときに1行で読み取るのです.では、どのようにしてすべてのヘッダを読み取ることができますか.理由は頭の後ろにあるrで、これを読み取ると頭が終了し、読み取りを行わないことを示し、サーバが読み取るときにブロックされることはありません.
4.サーバがデータを送信する場合、データサイズは過去に送信され、静的htmlページであれば直接content-lengthで表記され、動的であればchunkedで送信され、writeの前に、サイズwrite
要求ヘッダ情報を解析する際、tomcatはsocketのinputStreamの情報を読み出し、それを読み出すSocketInputStreamを提供する
httpリクエストヘッダフォーマットが次の場合
XXXX: XXX\r
XXXX: XXX\r
\r
したがって、socketInputStreamは毎回rまで読み込まれ、再び読み込まれます.
for(;;){
if(buffer[pos] == (byte)'\r')
continue;
} if(buffer[pos]==(byte)'')
break;
SOcketストリームを読み取る場合、いつ読み取りが停止するか分からないため、read()がブロックされるため、読み取り時に明確な停止限界を提出しなければならない
socketInputStreamは最後のrによって識別され、読み取る前に1つのrに言及すると、読み取りが完了したことを示す
以下はsocketInputStreamストリームを模した例であり,行でバイトを読み出し,rに遭遇して終了する.
4.サーバがデータを送信する場合、データサイズは過去に送信され、静的htmlページであれば直接content-lengthで表記され、動的であればchunkedで送信され、writeの前に、サイズwrite
要求ヘッダ情報を解析する際、tomcatはsocketのinputStreamの情報を読み出し、それを読み出すSocketInputStreamを提供する
httpリクエストヘッダフォーマットが次の場合
XXXX: XXX\r
XXXX: XXX\r
\r
したがって、socketInputStreamは毎回rまで読み込まれ、再び読み込まれます.
for(;;){
if(buffer[pos] == (byte)'\r')
continue;
} if(buffer[pos]==(byte)'')
break;
SOcketストリームを読み取る場合、いつ読み取りが停止するか分からないため、read()がブロックされるため、読み取り時に明確な停止限界を提出しなければならない
socketInputStreamは最後のrによって識別され、読み取る前に1つのrに言及すると、読み取りが完了したことを示す
以下はsocketInputStreamストリームを模した例であり,行でバイトを読み出し,rに遭遇して終了する.
package stream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
*
*
*
*
*/
public class LineInputStream {
private static final byte CR = (byte) '\r';
private static final byte LF = (byte) '
';
private static final int SIZE = 1024;
private byte[] buf;
private int pos;
private int count;
private InputStream in;
public LineInputStream(InputStream in, int size) {
this.in = in;
buf = new byte[size];
}
public LineInputStream(InputStream in) {
this(in, SIZE);
}
public int read() throws IOException {
if (pos >= count) {
fill();
if (pos >= count)
return -1;
}
return buf[pos++] & 0xff;
}
/**
* , \r
, null EOF , \r
,
* EOF \r
, \r
*
* @return
* @throws IOException
*/
public String readLine() throws IOException {
StringBuilder sb = new StringBuilder();
int ch = read();
if (ch == -1)
throw new EOFException(); // , socket, socket.close()
if (ch == CR || ch == LF) { // \r
,
read();
return null;
}
pos--;
while (true) {
if (pos >= count) {
fill();
if (pos >= count)
return sb.toString();
}
if (buf[pos] == CR) {
pos++;
continue;
}
if (buf[pos] == LF) {
pos++;
break;
}
sb.append((char) (buf[pos++] & 0xff));
}
return sb.toString();
}
public int readLine(byte[] buffer, int offset, int len) throws IOException {
//
if (buffer == null)
throw new NullPointerException();
if (offset < 0 || offset > buffer.length || len < 0
|| offset + len > buffer.length)
throw new ArrayIndexOutOfBoundsException();
int allBits = 0;
int ch = read();
if (ch == -1)
return -1;
if (ch == CR || ch == LF)
return -1;
pos--;
while(true) {
if(pos>=count)
{
fill();
if(pos>=count)
return allBits;
}
if(buf[pos]==CR)
{
pos++;
continue;
}
if(buf[pos]==LF || allBits==len) {
pos++;
break;
}
buffer[allBits++] = buf[pos++];
}
return allBits;
}
/*
* pos>=count , buf fill
*/
private void fill() throws IOException {
pos = 0;
count = 0;
int len = in.read(buf);
if (len > 0) //
count = len;
}
public static void main(String args[]) throws Exception {
LineInputStream lin = new LineInputStream(new FileInputStream(
"F:\\c.txt"), 4);
/*String line = null;
while ((line = lin.readLine()) != null) {
System.out.println(line);
}*/
byte[] buffer = new byte[100];
int len = -1;
while((len=lin.readLine(buffer, 0, buffer.length))!=-1) {
System.out.println(new String(buffer,0,len));
}
}
}