Java非阻塞NIO网络编程连接超时的处理

来源:互联网 发布:windows 10安装大小 编辑:程序博客网 时间:2024/06/10 23:06

在NIO网络编程中,需要使用如下语句来完成客户端对服务器的连接:

Selector selector = Selector.open();InetSocketAddress isa = new InetSocketAddress(host, port);// 调用open静态方法创建连接到指定主机的SocketChannelSocketChannel sc = SocketChannel.open(isa);

但却没有相关方法来设置超时参数,这就导致在调用open()方法时,如果连接不上服务器,那么此方法就会长时间阻塞(试了一下,大约阻塞了1-2分钟才抛出SocketTimeoutException),为了解决这个问题,我们可以在调用open()方法前,启动一个定时器,这个定时器会在指定的时间内检查是否已连接成功,这个指定的时间也就是我们希望设置的连接超时时间,当检查已连接上服务器时,提示用户已连接成功;若没有连接上,可在代码中抛出SocketTimeoutException,并提示用户连接超时。代码如下:

package com.test.thread;import java.io.IOException;import java.net.InetSocketAddress;import java.net.SocketTimeoutException;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.SocketChannel;import java.nio.charset.Charset;import java.util.Timer;import java.util.TimerTask;import android.os.Handler;import android.os.Message;public class NetworkNIOThread implements Runnable{// 定义处理编码和解码的字符集public static final Charset CHAR_SET = Charset.forName("GBK");// 定义检测SocketChannel的Selector对象private Selector selector;// 客户端SocketChannelprivate SocketChannel sc;private Handler handler;private String host;private int port;public NetworkNIOThread(Handler handler, String host, int port)throws IOException{this.handler = handler;this.host = host;this.port = port;}@Overridepublic void run(){connect();}public void connect(){try{selector = Selector.open();InetSocketAddress isa = new InetSocketAddress(host, port);//10秒连接超时new Timer().schedule(tt, 10000);// 调用open静态方法创建连接到指定主机的SocketChannelsc = SocketChannel.open(isa);// 设置该sc以非阻塞方式工作sc.configureBlocking(false);// 将Socketchannel对象注册到指定Selectorsc.register(selector, SelectionKey.OP_READ);Message msg = new Message();msg.what = 0;msg.obj = sc;handler.sendMessage(msg); // 连接成功new Thread(new NIOReceiveThread(selector, handler)).start();}catch (IOException e){e.printStackTrace();handler.sendEmptyMessage(-1); // IO异常}}TimerTask tt = new TimerTask(){@Overridepublic void run(){if (sc == null || !sc.isConnected()){try{throw new SocketTimeoutException("连接超时");}catch (SocketTimeoutException e){e.printStackTrace();handler.sendEmptyMessage(-6); // 连接超时}}}};}


原创粉丝点击