java nio 异步读取网络数据_java网络通信:异步非阻塞I/O (NIO)

public classTimeClient {public static voidmain(String[] args) {int port = 8080;new Thread(new TimeClientHandle("127.0.0.1", port), "TimeClient-001").start();

}

}public class TimeClientHandle implementsRunnable {privateString host;private intport;privateSelector selector;privateSocketChannel socketChannel;private volatile booleanstop;public TimeClientHandle(String host, intport) {this.host = host == null ? "127.0.0.1": host;this.port =port;try{

selector=Selector.open();

socketChannel=SocketChannel.open();

socketChannel.configureBlocking(false);

}catch(IOException e) {

e.printStackTrace();

System.exit(1);

}

}

@Overridepublic voidrun() {try{

doConnect();

}catch(IOException e) {

e.printStackTrace();

System.exit(1);

}while (!stop) {try{

selector.select(1000);

Set selectedKeys =selector.selectedKeys();

Iterator it =selectedKeys.iterator();

SelectionKey key= null;while(it.hasNext()) {

key=it.next();

it.remove();try{

handleInput(key);

}catch(Exception e) {if (key != null) {

key.cancel();if (key.channel() != null)

key.channel().close();

}

}

}

}catch(Exception e) {

e.printStackTrace();

System.exit(1);

}

}//多路复用器关闭后,所有注册在上面的Channel和Pipe等资源都会被自动去注册并关闭,所以不需要重复释放资源

if (selector != null)try{

selector.close();

}catch(IOException e) {

e.printStackTrace();

}

}private void doConnect() throwsIOException {//如果直接连接成功,则注册到多路复用器上,发送请求消息,读应答

if (!socketChannel.connect(newInetSocketAddress(host, port))) {

socketChannel.register(selector, SelectionKey.OP_READ);

doWrite(socketChannel);

}else//没有直接连接成功,不代表失败,而是说明服务器还没有返回TCP握手的应答消息,所以注册OP_CONNECT事件,监听消息。

socketChannel.register(selector, SelectionKey.OP_CONNECT); }private void handleInput(SelectionKey key) throwsIOException {if(key.isValid()) {//判断是否连接成功

SocketChannel sc =(SocketChannel) key.channel();if (key.isConnectable()) {//判断是否有连接事件,是的话,说明未连接

if (sc.finishConnect()) {//再连接

sc.register(selector, SelectionKey.OP_READ);

doWrite(sc);

}elseSystem.exit(1);//连接失败,进程退出

}if(key.isReadable()) {

ByteBuffer readBuffer= ByteBuffer.allocate(1024);int readBytes =sc.read(readBuffer);if (readBytes > 0) {

readBuffer.flip();byte[] bytes = new byte[readBuffer.remaining()];

readBuffer.get(bytes);

String body= new String(bytes, "UTF-8");

System.out.println("Now is : " +body);this.stop = true;

}else if (readBytes < 0) {//对端链路关闭

key.cancel();

sc.close();

}

}

}

}private void doWrite(SocketChannel sc) throwsIOException {byte[] req = "QUERY TIME ORDER".getBytes();

ByteBuffer writeBuffer=ByteBuffer.allocate(req.length);

writeBuffer.put(req);

writeBuffer.flip();

sc.write(writeBuffer);if (!writeBuffer.hasRemaining())

System.out.println("Send order 2 server succeed.");

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值