前言
在jdk1.4及以前版本中,从Socket中读取数据时,读取数据过程是阻塞进行的,且阻塞时间取决于数据发送方,但是通过设置读取数据最大超时时间后,就不会一直处于阻塞状态。当然,1.4版本API中加入了NIO技术,可以通过NIO实现非阻塞I/O(no-blocking I/O)操作。
示例
下面我们通过socket的setSoTimeout()方法来设置超时时间(单位毫秒),当接收端在超出了超时时间还没有接收到任何数据时,会抛出java.io.InterruptedIOException异常,代码示例如下:
import java.io.IOException;@b@import java.io.InputStream;@b@import java.io.InterruptedIOException;@b@import java.net.Socket;@b@import java.net.UnknownHostException;@b@@b@public class SocketSetTimeOutTest {@b@@b@ public static void main(String[] args) {@b@ @b@ int br=0;@b@ byte[] buffer=new byte[1024];@b@ @b@ try {@b@ Socket s=new Socket("localhost",8888);@b@ System.out.println(s.getSoTimeout());//打印默认超时时间@b@ s.setSoTimeout(5000);//设置超时时间5s@b@ InputStream is=s.getInputStream();@b@ while(true){@b@ try {@b@ br=is.read(buffer);@b@ if(br==-1){@b@ break;@b@ }@b@ System.out.println(new String(buffer,0,br));@b@ } catch (InterruptedIOException ee) {@b@ // TODO Auto-generated catch block@b@ System.out.println("read timeout 5s");@b@ }@b@ }@b@ @b@ } catch (UnknownHostException e) {@b@ // TODO Auto-generated catch block@b@ e.printStackTrace();@b@ } catch (IOException e) {@b@ // TODO Auto-generated catch block@b@ e.printStackTrace();@b@ } @b@@b@ }@b@@b@}
结合服务端代码(参见"如何利用Socket传输中文字符?"服务端代码示例),运行结果如下:
0@b@read timeout 5s@b@read timeout 5s@b@...
从结果可以看出,默认超时时间为0,意味着无限长时间,程序会一直等待有结果位置,这样就造成阻塞