HTTP协议 chunked

最近写了一个自己的http服务器(基于netty,但不使用netty自带的http协议包)。一般的请求都是直接使用指定content-length的方式去实现的,但对于一些大文件的传输效率则不太理想,之前一直只是大概知道分块传输,但一直没有真正码过相关代码,这次就尝试实现了一下。

总共三部分:

1、设置响应头

2、分块传输: 长度\r\n内容\r\n,长度为16进制字符串

3、空数据块:用于标记结束, 0\r\n\r\n

 

    private String CRLF = "\r\n";

	private void write(ChannelHandlerContext ctx) throws IOException {
		//响应头
		ctx.writeAndFlush(getHeaderByteBuf());
		
		//数据分块传输
		InputStream in = App.class.getClassLoader().getResourceAsStream("jquery-3.0.0.js");
		byte[] bs = new byte[1024];
		int len = 0;
		while((len = in.read(bs)) > 0) {
			ctx.writeAndFlush(getChunkedByteBuf(bs, len));
		}
		
		//空数据块表示结束
		ctx.writeAndFlush(getEnd());
	}
	
	/**
	 * 响应头信息
	 * @return
	 */
	private ByteBuf getHeaderByteBuf() {
		StringBuffer header = new StringBuffer();
		header.append("HTTP/1.1 200 OK").append(CRLF);
		header.append("content-type: application/javascript").append(CRLF);
		header.append("transfer-encoding: chunked").append(CRLF).append(CRLF);
		return Unpooled.copiedBuffer(header.toString().getBytes());
	}
	
	/**
	 * 获取chunked数据块
	 * size(16进制长度)\r\n content(具体内容)\r\n
	 * @param bs
	 * @param len
	 * @return
	 * @throws IOException
	 */
	private ByteBuf getChunkedByteBuf(byte[] bs, int len) throws IOException {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		//size\r\n
		out.write(Integer.toHexString(len).getBytes());
		out.write(CRLF.getBytes());
		
		//content\r\n
		out.write(bs, 0, len);
		out.write(CRLF.getBytes());
		return Unpooled.copiedBuffer(out.toByteArray());
	}
	
	/**
	 * 获取空数据块 0\r\n\r\n
	 * 空数据块是最后传输,表示数据结束
	 * @return
	 */
	private ByteBuf getEnd() {
		StringBuffer contentCount = new StringBuffer("0").append(CRLF).append(CRLF);
		return Unpooled.copiedBuffer(contentCount.toString().getBytes());
	}

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值