echo小例子
服务端
- import java.io.IOException;
- import java.net.InetSocketAddress;
- import java.net.ServerSocket;
- import java.nio.ByteBuffer;
- import java.nio.channels.SelectionKey;
- import java.nio.channels.Selector;
- import java.nio.channels.ServerSocketChannel;
- import java.nio.channels.SocketChannel;
- import java.util.Iterator;
- public class Ex2Server {
- /**
- * @param args
- * @throws IOException
- */
- public static void main(String[] args) throws IOException {
- //第一件事是创建一个 Selector
- Selector selector = Selector.open();
- //要监听的每一个端口都需要有一个 ServerSocketChannel
- ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
- serverSocketChannel.configureBlocking(false);
- ServerSocket serverSocket = serverSocketChannel.socket();
- serverSocket.bind(new InetSocketAddress(12345));//绑定一个端口
- //SelectionKey 代表这个通道在此 Selector 上的这个注册。
- //当某个 Selector 通知您某个传入事件时,它是通过提供对应于该事件的 SelectionKey 来进行的。
- //SelectionKey 还可以用于取消通道的注册。
- SelectionKey selectionKey = serverSocketChannel.register(
- selector, SelectionKey.OP_ACCEPT);//注册accept事件
- int num = 0;
- ByteBuffer buffer = ByteBuffer.allocate(1024);
- while(true){
- //select方法会阻塞,直到至少有一个已注册的事件发生
- num = selector.select();
- Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
- SelectionKey key = null;
- while(iterator.hasNext()){
- key = iterator.next();
- if(key.isAcceptable()){//accept
- ServerSocketChannel channel = (ServerSocketChannel)key.channel();
- //相当于从ServerSocket中accept一个socket
- SocketChannel socketChannel = channel.accept();
- socketChannel.configureBlocking(false);//设为非阻塞
- socketChannel.register(selector, SelectionKey.OP_READ);
- }else if(key.isReadable()){
- SocketChannel channel = (SocketChannel)key.channel();
- int readNum = 0;
- while(readNum != -1){
- buffer.clear();
- channel.read(buffer);//读出
- buffer.flip();
- channel.write(buffer);
- }
- //channel.close();
- }else if(key.isWritable()){
- }
- iterator.remove();
- }
- }
- }
- }
客户端
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.OutputStreamWriter;
- import java.io.PrintWriter;
- import java.net.InetSocketAddress;
- import java.net.Socket;
- import java.net.SocketAddress;
- public class Ex2Client {
- /**
- * @param args
- * @throws IOException
- */
- public static void main(String[] args) throws IOException {
- SocketAddress address = new InetSocketAddress("localhost", 12345);
- Socket s = new Socket();
- s.connect(address);
- PrintWriter writer = new PrintWriter( new OutputStreamWriter(s.getOutputStream()));
- writer.println("abc");
- writer.flush();
- BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
- System.out.println(reader.readLine());
- writer.close();
- reader.close();
- s.close();
- }
- }
如果写入的内容比较多,可以把读跟写分开
- import java.io.IOException;
- import java.net.InetSocketAddress;
- import java.net.ServerSocket;
- import java.nio.ByteBuffer;
- import java.nio.channels.SelectionKey;
- import java.nio.channels.Selector;
- import java.nio.channels.ServerSocketChannel;
- import java.nio.channels.SocketChannel;
- import java.util.Iterator;
- public class Ex2Server2 {
- /**
- * @param args
- * @throws IOException
- */
- public static void main(String[] args) throws IOException {
- //第一件事是创建一个 Selector
- Selector selector = Selector.open();
- //要监听的每一个端口都需要有一个 ServerSocketChannel
- ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
- serverSocketChannel.configureBlocking(false);
- ServerSocket serverSocket = serverSocketChannel.socket();
- serverSocket.bind(new InetSocketAddress(12345));//绑定一个端口
- //SelectionKey 代表这个通道在此 Selector 上的这个注册。
- //当某个 Selector 通知您某个传入事件时,它是通过提供对应于该事件的 SelectionKey 来进行的。
- //SelectionKey 还可以用于取消通道的注册。
- SelectionKey selectionKey = serverSocketChannel.register(
- selector, SelectionKey.OP_ACCEPT);//注册accept事件
- int num = 0;
- ByteBuffer buffer = ByteBuffer.allocate(1024);
- while(true){
- //select方法会阻塞,直到至少有一个已注册的事件发生
- num = selector.select();
- Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
- SelectionKey key = null;
- while(iterator.hasNext()){
- key = iterator.next();
- if(key.isAcceptable()){//accept
- ServerSocketChannel channel = (ServerSocketChannel)key.channel();
- //相当于从ServerSocket中accept一个socket
- SocketChannel socketChannel = channel.accept();
- socketChannel.configureBlocking(false);//设为非阻塞
- socketChannel.register(selector, SelectionKey.OP_READ);
- }else if(key.isReadable()){
- SocketChannel channel = (SocketChannel)key.channel();
- int readNum = 1;
- while(readNum > 0){
- buffer.clear();
- readNum = channel.read(buffer);//读出
- buffer.flip();
- //channel.write(buffer);
- }
- channel.register(selector, SelectionKey.OP_WRITE);
- //channel.close();
- }else if(key.isWritable()){
- SocketChannel channel = (SocketChannel)key.channel();
- buffer.clear();
- buffer.put("测试\r\n".getBytes());
- buffer.flip();
- channel.write(buffer);
- //取消写入key的注册,不然一直可写
- key.cancel();
- //改正:key.cancel会把channel也关闭,这里设置OPS为读,也就把写给反注册掉了
- key.interestOps(SelectionKey.OP_READ);
- }
- iterator.remove();
- }
- }
- }
- }
本文转自 dogegg250 51CTO博客,原文链接:http://blog.51cto.com/jianshusoft/692761,如需转载请自行联系原作者