NIO使用实例

具体的就不多讲了这里只是一个简单的例子,方便本人日后查阅

SERVER:

import java.net.InetSocketAddress;
import java.net.StandardSocketOptions;
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.Set;
import static java.nio.channels.SelectionKey.OP_READ;
/**
 * Created by sunzhengfang on 2017/9/7.
 */
public class NioTest {

    public static void main(String[] args){

        try {
            //先在这里准备一个selector
            Selector selector = Selector.open();
            //启动一个监听的通道
            ServerSocketChannel serverChannel = ServerSocketChannel.open();
            serverChannel.configureBlocking(false);
            serverChannel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
            serverChannel.setOption(StandardSocketOptions.SO_RCVBUF, 1024 * 16 * 2);
            serverChannel.bind(new InetSocketAddress("localhost", 8888), 100);
            //将我们的selector注册到这里channel里面
            serverChannel.register(selector, SelectionKey.OP_ACCEPT);

            //完成上述步骤之后我们其实已经开始了监听,但是我们还没能获取到其中的输入信息
            //需要通过一个循环来获取selector中的信息

            while(true){
                try {
                    selector.select(1000L);
                    Set<SelectionKey> keys = selector.selectedKeys();
                    try {
                        for (SelectionKey key : keys) {
                            if (key.isValid() && key.isAcceptable()) {
                                //这里是连接刚刚连上的时候在这里既然连接上了
                                // 我们需要把这个具体的连接拿出来
                                SocketChannel clientChannel = ((ServerSocketChannel) key.channel()).accept();
                                clientChannel.configureBlocking(false);
                                //拿出来之后我们需要改变这个NIO的状态然后将这个通道注册回去
                                clientChannel.register(key.selector(), OP_READ, ByteBuffer.allocate(1024));
                            } else if(key.isReadable()){
                                //获取到响应的通道
                                SocketChannel clientChannel = (SocketChannel) key.channel();
                                //获取连接中的buf
                                ByteBuffer buf = (ByteBuffer) key.attachment();
                                int bytesRead = clientChannel.read(buf);
                                if (bytesRead == -1) {
                                    clientChannel.close();
                                } else if (bytesRead > 0) {
                                    key.interestOps(SelectionKey.OP_WRITE);
                                    System.out.println("Get data: " +new String(buf.array()));
                                }
                            } else if (key.isValid() && key.isWritable()) {
                                System.out.println("is write");
                                ByteBuffer buf = (ByteBuffer) key.attachment();
                                buf.clear();
                                buf.put("heiheihei".getBytes());
                                buf.flip();
                                SocketChannel clientChannel = (SocketChannel) key.channel();
                                clientChannel.finishConnect();
                                clientChannel.write(buf);
                                if (!buf.hasRemaining()) {
                                    key.interestOps(OP_READ);
                                }
                                buf.compact();
                            }
                            else {
                                key.cancel();
                            }
                        }
                    } finally {
                        keys.clear();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    System.out.println("some thing wrong with this");
                }
            }


        }catch (Exception e){

        }
    }



}
CLIENT:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Set;

/**
 * Created by XH on 2017/9/7.
 */
public class NioClientTest {

    /*标识数字*/
    private static int flag = 0;

    public static void main(String[] args) throws Exception {
        // 打开socket通道
        SocketChannel socketChannel = SocketChannel.open();
        // 设置为非阻塞方式
        socketChannel.configureBlocking(false);
        // 打开选择器
        Selector selector = Selector.open();
        // 注册连接服务端socket动作
        socketChannel.register(selector, SelectionKey.OP_CONNECT);
        // 连接
        socketChannel.connect(new InetSocketAddress("localhost", 8888));
        // 分配缓冲区大小内存

        Set<SelectionKey> selectionKeys;
        SocketChannel client;
        String receiveText;
        String sendText;
        int count=0;

        while (true) {
            selector.select();
            //返回此选择器的已选择键集。
            selectionKeys = selector.selectedKeys();
            for (SelectionKey selectionKey:selectionKeys) {
                if (selectionKey.isConnectable()) {
                    System.out.println("client connect");
                    client = (SocketChannel) selectionKey.channel();
                    // 判断此通道上是否正在进行连接操作。
                    // 完成套接字通道的连接过程。
                    if (client.isConnectionPending()) {
                        client.finishConnect();
                        System.out.println("connect success");
                        ByteBuffer sendbuffer = ByteBuffer.allocate(1024);
                        sendbuffer.clear();
                        sendbuffer.put("gua pi".getBytes());
                        sendbuffer.flip();
                        client.write(sendbuffer);
                    }
                    //发送完之后就复位,准备读取输入
                    client.register(selector, SelectionKey.OP_READ);
                } else if (selectionKey.isReadable()) {
                    client = (SocketChannel) selectionKey.channel();
                    ByteBuffer receivebuffer = ByteBuffer.allocate(1024);
                    count=client.read(receivebuffer);
                    if(count>0){
                        receiveText = new String( receivebuffer.array(),0,count);
                        System.out.println("recive data:"+receiveText);
                        client.register(selector, SelectionKey.OP_WRITE);
                    }

                } else if (selectionKey.isWritable()) {
                    System.out.println("is write");
                    ByteBuffer sendbuffer = ByteBuffer.allocate(1024);
                    sendbuffer.clear();
                    client = (SocketChannel) selectionKey.channel();
                    sendbuffer.put("sunsun314".getBytes());
                    sendbuffer.flip();
                    client.finishConnect();
                    client.write(sendbuffer);
                    client.register(selector, SelectionKey.OP_READ);
                }
            }
            selectionKeys.clear();
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值