NIO操作
2019-01-01 本文已影响0人
笑才
public class MyNioServer {
private Selector selector;//创建一个选择器
private final static int port = 8686;
private final static int BUF_SIZE = 10240;
private void initServer() throws IOException{
//创建通道管理器对象Selector
this.selector = Selector.open();
//创建一个通道对象channel
ServerSocketChannel channel = ServerSocketChannel.open();
//将通道设为非阻塞
channel.configureBlocking(false);
//将端口绑定在8686端口上
channel.socket().bind(new InetSocketAddress(port));
//将上述的通道管理器和通道绑定,并为该通道注册OP_ACCEPT事件
//注册事件后,当该事件到达时,selector.select()会返回(一个key),如果该事件没有到达selector.select()会一直阻塞
SelectionKey selectionKey = channel.register(selector, SelectionKey.OP_ACCEPT);
while(true){//轮询
//这是一个阻塞方法,一直等待直到有数据可读,返回值是key的数量(可以有多个)
selector.select();
//如果channel有数据了,将生成的key放入keys集合中
Set keys = selector.selectedKeys();
//得到这个keys的集合的迭代器
Iterator iterator = keys.iterator();
while(iterator.hasNext()){//使用迭代器遍历集合
//得到集合中的一个key的实例
SelectionKey key = (SelectionKey) iterator.next();
//拿到当前key实例之后记得在迭代器中将这个元素删除,否则会出错
iterator.remove();
if(key.isAcceptable()){//判断当前key所代表的channel是否在Acceptable状态,如果是就进行接受
doAccept(key);
}else if(key.isReadable()){
doRead(key);
}else if(key.isWritable() && key.isValid()){
doWrite(key);
}else if(key.isConnectable()){
System.out.println("连接成功");
}
}
}
}
public void doAccept(SelectionKey key) throws IOException{
ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
System.out.println("ServerSocketChannel正在监听");
SocketChannel clientChannel = serverChannel.accept();
clientChannel.configureBlocking(false);
clientChannel.register(key.selector(),SelectionKey.OP_READ);
}
public void doRead(SelectionKey key) throws IOException{
SocketChannel clientChannel = (SocketChannel) key.channel();
ByteBuffer byteBuffer = ByteBuffer.allocate(BUF_SIZE);
long bytesRead = clientChannel.read(byteBuffer);
while(bytesRead>0){
byteBuffer.flip();
byte[] data = byteBuffer.array();
String info = new String(data);
System.out.println("从客户端发送过来的消息是:"+info);
byteBuffer.clear();
bytesRead = clientChannel.read(byteBuffer);
}
if(bytesRead==-1){
clientChannel.close();
}
}
public void doWrite(SelectionKey key) throws IOException{
ByteBuffer byteBuffer = ByteBuffer.allocate(BUF_SIZE);
byteBuffer.flip();
SocketChannel clientChannel = (SocketChannel) key.channel();
while(byteBuffer.hasRemaining()){
clientChannel.write(byteBuffer);
}
byteBuffer.compact();
}
public static void main(String[] args) throws IOException{
MyNioServer myNioServer = new MyNioServer();
myNioServer.initServer();
}
}
public class MyNioClient {
private Selector selector;
private final static int port = 8686;
private final static int BUF_SIE = 10240;
private static ByteBuffer byteBuffer = ByteBuffer.allocate(BUF_SIE);
private void initClient() throws IOException{
this.selector = Selector.open();
SocketChannel clientChannel = SocketChannel.open();
clientChannel.configureBlocking(false);
clientChannel.connect(new InetSocketAddress(port));
clientChannel.register(selector, SelectionKey.OP_CONNECT);
while(true){
selector.select();
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while(iterator.hasNext()){
SelectionKey key = iterator.next();
iterator.remove();
if(key.isConnectable()){
doConnect(key);
}else if(key.isReadable()){
doRead(key);
}
}
}
}
public void doConnect(SelectionKey key) throws IOException{
SocketChannel clientChannel = (SocketChannel) key.channel();
if(clientChannel.isConnectionPending()){
clientChannel.finishConnect();
}
clientChannel.configureBlocking(false);
String info = "服务端,你好!!";
byteBuffer.clear();
byteBuffer.put(info.getBytes("UTF-8"));
byteBuffer.flip();
clientChannel.write(byteBuffer);
clientChannel.close();
}
public void doRead(SelectionKey key) throws IOException{
SocketChannel clientChannel = (SocketChannel) key.channel();
clientChannel.read(byteBuffer);
byte[] data = byteBuffer.array();
String msg = new String(data).trim();
System.out.println("服务端发送消息:"+msg);
clientChannel.close();
key.selector().close();
}
public static void main(String[] args) throws IOException {
MyNioClient myNioClient = new MyNioClient();
myNioClient.initClient();
}
}