4.而服务器发送数据的时候,会将数据大小发送过去,如果是静态html页面的话,就直接 content-length标明,如果是动态的话,以chunked发送,每次write前,将大小write
在解析请求头信息时,tomcat 提供了一个SocketInputStream 来读取socket 中 inputStream 中的信息,将其读取出来
然后进行解析,由于 http请求头格式如果下
XXXX: XXX\r\n
XXXX: XXX\r\n
\r\n
所以,socketInputStream 每次就读取直到 \r\n,然后再次读取,就是形如:
for(;;){
if(buffer[pos] == (byte)'\r')
continue;
} if(buffer[pos]==(byte)'\n')
break;
在读取socket 流时,由于不知道什么时候读取停止,会造成 read() 阻塞,所以,读取时一定要提交明确的停止界限
而 socketInputStream 则是根据最后的 \r\n 来标识的,在 读取前,如果则上来就讲到一个\r\n,则表明读取完毕
下面是一个模仿socketInputStream 流的例子,也是以行来读取字节,遇到 \r\n来结束
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) '\n'; 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\n为结束标记,读取结束返回 null 读取结束与 EOF 不同,读取结束以 \r\n正学结束,停止外部的循环读取 * 而EOF不是以 \r\n为结束,而是在\r\n之前流 * * @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\n,表明必送结束 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)); } } }