您的位置:首页 > 理论基础 > 计算机网络

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

2013-08-03 15:55 519 查看
在NIO网络编程中,需要使用如下语句来完成客户端对服务器的连接:

Selector selector = Selector.open();
InetSocketAddress isa = new InetSocketAddress(host, port);
// 调用open静态方法创建连接到指定主机的SocketChannel
SocketChannel 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;

// 客户端SocketChannel
private 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;
}

@Override
public void run()
{
connect();
}

public void connect()
{
try
{
selector = Selector.open();
InetSocketAddress isa = new InetSocketAddress(host, port);
//10秒连接超时
new Timer().schedule(tt, 10000);
// 调用open静态方法创建连接到指定主机的SocketChannel
sc = SocketChannel.open(isa);
// 设置该sc以非阻塞方式工作
sc.configureBlocking(false);
// 将Socketchannel对象注册到指定Selector
sc.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()
{

@Override
public void run()
{
if (sc == null || !sc.isConnected())
{
try
{
throw new SocketTimeoutException("连接超时");
}
catch (SocketTimeoutException e)
{
e.printStackTrace();
handler.sendEmptyMessage(-6); // 连接超时
}
}
}

};
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  网络编程 socket nio