java nio通信_Java IO系列之四:NIO通信模型

importjava.io.IOException;importjava.net.InetSocketAddress;importjava.nio.ByteBuffer;importjava.nio.channels.SelectionKey;importjava.nio.channels.Selector;importjava.nio.channels.SocketChannel;importjava.util.Iterator;importjava.util.Set;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{//第一步:打开SocketChannel,用于创建客户端连接

socketChannel =SocketChannel.open();//第二步:设置SocketChannel为非阻塞模式

socketChannel.configureBlocking(false);//第三步:创建多路复用器(在Reactor线程中)

selector =Selector.open();

}catch(IOException e) {

e.printStackTrace();

System.exit(1);

}

}

@Overridepublic voidrun() {try{//第四步:socketChannel发起连接

if (socketChannel.connect(newInetSocketAddress(host, port))) {//第五步:如果直接连接成功,则注册到多路复用器上

socketChannel.register(selector, SelectionKey.OP_READ);//第六步:发送请求消息,读应答

byte[] req = "QUERY TIME ORDER".getBytes();

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

writeBuffer.put(req);

writeBuffer.flip();

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

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

}elsesocketChannel.register(selector, SelectionKey.OP_CONNECT);

}catch(IOException e) {

e.printStackTrace();

System.exit(1);

}while (!stop) {try{//第七步:多路复用器在run的无限循环体内轮询准备就绪的Key

selector.select(1000);

Set selectedKeys =selector.selectedKeys();

Iterator it =selectedKeys.iterator();

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

key=it.next();

it.remove();try{if(key.isValid()) {//第八步:将连接成功的Channel注册到多路复用器上//判断是否连接成功

SocketChannel sc =(SocketChannel) key.channel();if(key.isConnectable()) {if(sc.finishConnect()) {

sc.register(selector, SelectionKey.OP_READ);//发送请求消息,读应答

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.");

}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();

}else;//读到0字节,忽略

}

}

}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();

}

}

}packagecom.dxz.springsession.nio.demo6;public classTimeClient {/***@paramargs*/

public static voidmain(String[] args) {int port = 1234;if (args != null && args.length > 0) {try{

port= Integer.valueOf(args[0]);

}catch(NumberFormatException e) {//采用默认值

}

}new Thread(new TimeClientHandle("127.0.0.1", port), "TimeClient-001")

.start();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值