Socket编程中,有时会需要这样一种情况:服务器不断的向输出流中输出数据,客户端不断的读取数据。同时,只要客户端的输入流中有可读的数据,立即读取,如果没有,则阻塞等待。
但是客户端的输入流不可能保证在它想读数据的时候就一定会有可读的数据,如果直接去读的话就会抛出异常,为了避免这种情况的发生,一般的做法是在读取数据前先检查输入流中是否有可读数据:有,读取;没有,等待。就像下面的一样,这里省去服务器部分,强调重点在检查、读取:
Socket socket = new Socket("localhost", 227);
InputStream is = socket.getInputStream();
while(is.available() <= 0) { //如果没有可读取数据,则在此循环,直到有数据为止才继续执行
}
is.read();
然而,这样做会带来一个严重的后果,假设检查部分的代码是在多线程中,并且程序稍稍复杂一点点,比如有同时有几个流都要读取,这样互相抢占资源的情况下难免会出现死锁现象。
今天无意间发现了一个平时不太注意的东西,“Timeout”,在Java的Socket里有一个
setSoTimeout(int
)的方法,用它来设置阻塞时间,在规定的时间里如果得不到资源,那就直接抛出异常,这样既解决了直接读取发生错误的问题,又防止死锁的发生。这样,代码可以改成:
Socket socket = new Socket("localhost", 227);
socket.setSoTimeout(10000); //设置时延时间,单位毫秒
InputStream is = socket.getInputStream();
//在设置好Timeout后,可以直接读取数据
//如果没有可读数据,系统会自动等上一段时间
//在规定的时间内还没有数据的话再抛异常
is.read();
这样,问题得到彻底解决。
阅读(5661) | 评论(0) | 转发(0) |