Toma4.1实现HTTP/1.1持久化处理(以行读取字节流)

来源:互联网 发布:苹果网络授权经销商 编辑:程序博客网 时间:2024/06/04 18:52
1.浏览器在发送数据的时候,如果是get方式,直接发送,如果是 post方式会发送content-length表明发送数据的大小
2.浏览器在接收数据的时候一般都会知道要接收数据的大小,这样浏览器不至于盲目等待和阻塞
3.服务器在读取请求的时候是以一行来读取.那么它是怎么知道读取完所有有头的呢?原因就在头后面的一个\r\n,如果读取这个就表明头结束,不再下读取,这样就不会造成
服务器读取的时候阻塞

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));}    }}


原创粉丝点击