java-nio代码模拟

server:

package com.io;

import com.mysql.fabric.Server;

import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class NioServer {
    Selector selector;
    ServerSocketChannel ssc;
    private ExecutorService service = Executors.newFixedThreadPool(5);

    public void init() {
        try {
            ssc= ServerSocketChannel.open();
            ssc.bind(new InetSocketAddress("127.0.0.1",7878));
            ssc.configureBlocking(false);
            selector= Selector.open();
            ssc.register(selector, SelectionKey.OP_ACCEPT);
            System.out.println("server....start.....");
        }catch (Exception e){
            e.printStackTrace();
        }
    }


    public void accept(SelectionKey selectionKey){
        try {
            ServerSocketChannel scc = (ServerSocketChannel) selectionKey.channel();
            SocketChannel sc = scc.accept();
            sc.configureBlocking(false);
            sc.register(selector,SelectionKey.OP_READ);
            System.out.println("=====acceptfinish==========="+sc.socket().getInetAddress().getHostName());
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("===============================");
        }

    }
    public void start(){
        init();
        while (true){
            System.out.println("1111111111111111111111111111111111111");
            try {
                int event = selector.select();
                if (event >= 1) {
                    Iterator<SelectionKey> it = selector.selectedKeys().iterator();
                    while (it.hasNext()) {
                        System.out.println("2222222222222222222222222222222222222222222");
                        SelectionKey selectionKey = it.next();
                        if(selectionKey.isAcceptable()){
                            System.out.println("=========接受======");
                            accept(selectionKey);
                        }else if(selectionKey.isReadable()){
                            System.out.println("====read========="+selectionKey.isReadable());
                            service.submit(new HandleSocket(selectionKey));
                            Thread.sleep(5000);
                            System.out.println("============沉睡结束==========");

                        }
                        it.remove();
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
            }

        }
    }

    public static void main(String[] args) {
        new NioServer().start();
    }
}

client:

package com.io;

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.Iterator;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class NioClient {
    private Selector selector;
    public void connect(){
        try {
            SocketChannel socketChannel = SocketChannel.open();
            socketChannel.configureBlocking(false);
            this.selector = Selector.open();
            // 为通道注册连接事件,当该事件到达时,selector.select()会返回
            socketChannel.register(selector, SelectionKey.OP_CONNECT);
            socketChannel.connect(new InetSocketAddress("127.0.0.1",7878));
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("=============err==================");
        }
    }

    public Selector getSelector() {
        return selector;
    }

    public void setSelector(Selector selector) {
        this.selector = selector;
    }

    public static void main(String[] args) {
        ExecutorService es = Executors.newFixedThreadPool(5);
        for(int i=0;i<1;i++){
            es.submit(new Runnable() {
                @Override
                public void run() {
                    NioClient nioClient = new NioClient();
                    nioClient.connect();
                    nioClient.runHandle();
                }
            });
        }

    }
    public void runHandle(){
        try {
            while (true) {
                int event = selector.select();
                if (event >= 1) {
                    Iterator<SelectionKey> it = selector.selectedKeys().iterator();
                    while (it.hasNext()) {
                        SelectionKey selectionKey = it.next();
                        it.remove();
                        if (selectionKey.isConnectable()) {
                            System.out.println();
                            SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                            if (socketChannel.isConnectionPending()) {
                                socketChannel.finishConnect();
                            }
                            socketChannel.configureBlocking(false);
                            socketChannel.register(selector,SelectionKey.OP_READ);
                            System.out.println("==============================");
                            ByteBuffer bf = ByteBuffer.allocate(1024);
                            bf.put("Hi,server,i'm client".getBytes());
                            bf.flip();
                            while (bf.hasRemaining()){
                                socketChannel.write(bf);
                            }
                        } else {
                            System.out.println("==读取==" + selectionKey.isReadable());
                            SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                            socketChannel.read(byteBuffer);
                            System.out.println("读取到数据==" + new String(byteBuffer.array()));
                            socketChannel.close();
                        }
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

其中遇到问题:client断开,server还会接收到空数据。原因是 while(true)一直再刷,刷到read丢给了一个线程去执行,然后接着刷,有可能会刷到上一个selectkey…在刷到后加个sleep就不会出现问题了,,一般是在刷到后去注销读事件。。。所以后面加了个sleep。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值