java nio2_javanio2

packagecom.lanhuigu.nio.selector;importjava.io.IOException;importjava.net.InetSocketAddress;importjava.nio.ByteBuffer;importjava.nio.channels.SelectionKey;importjava.nio.channels.Selector;importjava.nio.channels.SocketChannel;importjava.util.Iterator;public classNIOClient {privateSelector selector;public void initClient(String ip, int port) throwsIOException {

SocketChannel channel=SocketChannel.open();//设置通道为非阻塞

channel.configureBlocking(false);this.selector =Selector.open();//客户端连接服务器,其实方法执行并没有实现连接,需要在listen()方法中调用channel.finishConnect();才能完成连接

channel.connect(new InetSocketAddress(ip, port)); //channel连接通了,传统IO是连接上了之后就通过IO流来传输数据。服务端selector就会得到OP_ACCEPT事件select方法就会返回。//将通道管理器和该通道绑定,并为该通道注册SelectionKey.OP_CONNECT事件

SelectionKey selectionKey1 = channel.register(selector, SelectionKey.OP_CONNECT); //channel和selector绑定,这个selector关心这个channel的OP_CONNECT事件,selector的通道数组里面只有一个。

int interestSet = selectionKey1.interestOps();//感兴趣的是8,准备好的是0,

boolean isInterestedInAccept = (interestSet & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT;//false

int isInterestedInConnect = interestSet & SelectionKey.OP_CONNECT;//8

int isInterestedInRead = interestSet & SelectionKey.OP_READ;//0

int isInterestedInWrite = interestSet & SelectionKey.OP_WRITE;//0

int readySet = selectionKey1.readyOps();//0

}@SuppressWarnings("unchecked")public void listen() throwsException {while (true) {/** 选择一组可以进行I/O操作的事件,放在selector中,客户端的该方法不会阻塞,

* selector的wakeup方法被调用,方法返回,而对于客户端来说,通道一直是被选中的

* 这里和服务端的方法不一样,查看api注释可以知道,当至少一个通道被选中时。*/

int I = selector.select();//OP_CONNECT事件已有,不会阻塞//获得selector中选中的项的迭代器

Iterator ite = this.selector.selectedKeys().iterator();while(ite.hasNext()) {

SelectionKey key=(SelectionKey) ite.next();//删除已选的key,以防重复处理

ite.remove();//连接事件发生

if(key.isConnectable()) {//如果正在连接,则完成连接

SocketChannel channel =(SocketChannel) key.channel();if (channel.isConnectionPending()) {//该方法返回true表示连接成功

channel.finishConnect();

}//设置成非阻塞

channel.configureBlocking(false);//在这里可以给服务端发送信息哦

channel.write(ByteBuffer.wrap(new String("hello server!").getBytes()));//在和服务端连接成功之后,为了可以接收到服务端的信息,需要给通道设置读的权限。

SelectionKey selectionKey2 = channel.register(this.selector, SelectionKey.OP_READ); //获得了可读的事件,此时感兴趣是1准备好是8,selector数组里面还是只有一个SelectionKeyImpl//这个selctor关心这个channel的OP_READ和OP_CONNECT事件,并且只有这一个channel.

int interestSet = selectionKey2.interestOps();//1

boolean isInterestedInAccept = (interestSet & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT;//fasle

int isInterestedInConnect = interestSet & SelectionKey.OP_CONNECT;//0

int isInterestedInRead = interestSet & SelectionKey.OP_READ;//1

int isInterestedInWrite = interestSet & SelectionKey.OP_WRITE;//0

int readySet =selectionKey2.readyOps();

}else if(key.isReadable()) {

read(key);

}

}

}

}private void read(SelectionKey key) throwsException {

SocketChannel channel=(SocketChannel) key.channel();//分配缓冲区

ByteBuffer buffer = ByteBuffer.allocate(10);

channel.read(buffer);byte[] data =buffer.array();

String msg= newString(data).trim();

System.out.println("client receive msg from server:" +msg);

ByteBuffer outBuffer=ByteBuffer.wrap(msg.getBytes());

channel.write(outBuffer);

}

public static void main(String[] args) throwsException {

NIOClient client= newNIOClient();

client.initClient("localhost", 8989);

client.listen();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值