采用Java阻塞IO对已经到达的socket流实现非阻塞完整读取(一个简单的java http server实现)

该博客探讨了如何使用Java阻塞I/O(BIO)在没有传输协议信息的情况下,一次性完整读取已到达的Socket流。通过分析不同解法的优缺点,提出利用`ready()`函数来测试是否能非阻塞读取,最终实现了一个简单的HTTP Server,该服务器能根据用户请求返回相应的HTML响应,甚至支持关闭服务器的命令。
摘要由CSDN通过智能技术生成

最近写服务器时想到一个问题:用Java Bio(即Socket)写服务器,怎么一次性完整读取已经到达的Socket流。


对这个需求有很多角度的设定,也有很多解法。我们来一一具化这个需求:

(1)

解法:依赖http协议的content-length。

分析:很直观的想法,可以根据http请求头给定一个固定长度的字节或字符缓存,从中获取content-length,就知道往后要在从流中读多少字节了。

设定:如果不考虑http,设置也不考虑任何定制的协议(流的开头给长度或者用特殊的字符标志留的结尾),仅仅考虑一次socket流的到达,如何才能用完整读取这次到达流的内容。


(2)

解法:上nio上mina上netty。

分析:又直观的想法。不过开篇设定好了用阻塞读来实现非阻塞完整读取到达流。

设定:如何用java阻塞读(bio)达到不阻塞的完整读取一次socket到达流。


(3)

解法:依赖流的结尾返回-1。

分析:更直观的想法,java.io(也就是bio啦)提供的各种XXStream和XXReader都提供read(XX)的函数,并提示如果读到结尾就返回-1。那在服务器端直接不断read(),直到-1就好了。问题是对于文件的读取,到达结尾会返回-1(好像是文件末尾的EOF?具体没研究过)。但是socket流,是没有结束符的(其实也有,一个socket关闭后再read就会返回-1,但是这里对于一个已经到达的流的完整读取,肯定不能依赖于网络对面对socket关闭)。虽然文件流是连续的,但是网络流肯定不能保证,即便通过socket发送一个完整的文件,由于网络原因,这个文件可能分几个部分到达socket,而本文的需求就设定在对一次到达的流,怎么保证完整的读取。


(4)

解决:用大缓存。

分析:更加直观的想法。上个足够大的缓存,一次性把到达流的内容全部读出来&#

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值