• ServerSocketChannel和SocketChannel


    服务端代码

    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.net.ServerSocket;
    import java.net.Socket;
    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.nio.charset.Charset;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;
    
    
    /**
     * @program: smbTest
     * @description:
     * @author: hw
     * @create: 2020-10-22 15:30
     */
    public class NIOSServer implements Runnable {
        private int port = 445;
        private Charset cs = Charset.forName("gbk");
        private ByteBuffer sBuffer = ByteBuffer.allocate(1024);
        private ByteBuffer rBuffer = ByteBuffer.allocate(1024);
        private Map<String, SocketChannel> clientsMap = new HashMap<String, SocketChannel>();
        private Selector selector;
    
        public NIOSServer(int port) {
            this.port = port;
            try {
                init();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        private void init() throws IOException {
            // 创建ServerSocketChannel通道
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            // 设置为非阻塞模式
            serverSocketChannel.configureBlocking(false);
            ServerSocket serverSocket = serverSocketChannel.socket();
            // 绑定监听端口
            serverSocket.bind(new InetSocketAddress(port));
            // 注册选择器,设置选择器选择的操作类型
            selector = Selector.open();
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
            System.out.println("[SMB] SMB Server starting");
            System.out.println("[SMB] Listening for connections on [SMB,TCP-SMB,ALL:" + port + "]");
            System.out.println("[SMB] Waiting for new connection ...");
        }
    
        @Override
        public void run() {
            while (true) {
                try {
                    selector.select();
                    Set<SelectionKey> selectionKeys = selector.selectedKeys();
                    for (SelectionKey key : selectionKeys) {
                        handle(key);
                    }
                    selectionKeys.clear();
                } catch (Exception e) {
                    e.printStackTrace();
                    break;
                }
            }
        }
    
        private void handle(SelectionKey selectionKey) throws IOException{
            ServerSocketChannel server = null;
            SocketChannel client = null;
            String receiveText = null;
            int count = 0;
            if (selectionKey.isAcceptable()) {
                // 通过选择器键获取服务器套接字通道
                server = (ServerSocketChannel) selectionKey.channel();
                // 通过accept()方法获取套接字通道连接
                client = server.accept();
                //判断client 是否为空
                if (client != null) {
                    // 设置套接字通道为非阻塞模式
                    client.configureBlocking(false);
                    // 为套接字通道注册选择器,该选择器为服务器套接字通道的选择器,即选择到该SocketChannel的选择器
                    // 设置选择器关心请求为读操作,设置数据读取的缓冲器容量为处理器初始化时候的缓冲器容量
                    client.register(selector, SelectionKey.OP_READ);
                    System.out.println("[SMB] Connection from " + client.socket().getRemoteSocketAddress());
                }
            } else if (selectionKey.isReadable()) {
                // 获取套接字通道
                client = (SocketChannel) selectionKey.channel();
                rBuffer.clear();
                count = client.read(rBuffer);
                if (count > 0) {
                    rBuffer.flip();
                    receiveText = String.valueOf(cs.decode(rBuffer).array());
                    System.out.println("[SMB] "+client.socket().getRemoteSocketAddress() + ":" + receiveText);
                    dispatch(client, receiveText);
                    client = (SocketChannel) selectionKey.channel();
                    client.register(selector, SelectionKey.OP_READ);
                }
            }
        }
    
        private void dispatch(SocketChannel client, String info) throws IOException {
            Socket s = client.socket();
            String name = "[" + s.getInetAddress().toString().substring(1) + ":" + Integer.toHexString(client.hashCode()) + "]";
            if (!clientsMap.isEmpty()) {
                for (Map.Entry<String, SocketChannel> entry : clientsMap.entrySet()) {
                    SocketChannel temp = entry.getValue();
                    if (!client.equals(temp)) {
                        sBuffer.clear();
                        sBuffer.put((name + ":" + info).getBytes());
                        sBuffer.flip();
                        temp.write(sBuffer);
                    }
                }
            }
            clientsMap.put(name, client);
        }
    
        public static void main(String[] args) {
            NIOSServer server = new NIOSServer(1445);
            new Thread(server).start();
    
            NIOClient client = new NIOClient("192.168.120.67",1445);
            new Thread(client).start();
    
            NIOClient client2 = new NIOClient("192.168.120.67",1445);
            new Thread(client2).start();
        }
    }
    

      

    客户端代码

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    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.Date;
    import java.util.Set;
    
    
    /**
     * @program: smbTest
     * @description:
     * @author: hw
     * @create: 2020-10-22 16:01
     */
    public class NIOClient implements Runnable{
        private ByteBuffer sBuffer = ByteBuffer.allocate(1024);
        private ByteBuffer rBuffer = ByteBuffer.allocate(1024);
        private InetSocketAddress SERVER;
        private Selector selector;
        private SocketChannel client;
        private String receiveText;
        private String sendText;
        private int count=0;
    
        public NIOClient(String ip, int port){
            SERVER = new InetSocketAddress(ip, port);
            init();
        }
        public void init(){
            try {
                SocketChannel socketChannel = SocketChannel.open();
                socketChannel.configureBlocking(false);
                selector = Selector.open();
                socketChannel.register(selector, SelectionKey.OP_CONNECT);
                socketChannel.connect(SERVER);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void run() {
            try {
                while (true) {
                    selector.select();
                    Set<SelectionKey> keySet = selector.selectedKeys();
                    for(final SelectionKey key : keySet){
                        handle(key);
                    }
                    keySet.clear();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        private void handle(SelectionKey selectionKey) throws IOException{
            if (selectionKey.isConnectable()) {
                client = (SocketChannel) selectionKey.channel();
                if (client.isConnectionPending()) {
                    client.finishConnect();
                    System.out.println("connect success !");
                    sBuffer.clear();
                    sBuffer.put((new Date()+" connected!").getBytes());
                    sBuffer.flip();
                    client.write(sBuffer);
                    //启动线程监听控制台输入并发送到客户端
                    new Thread(){
                        @Override
                        public void run() {
                            while(true){
                                try {
                                    sBuffer.clear();
                                    InputStreamReader input = new InputStreamReader(System.in);
                                    BufferedReader br = new BufferedReader(input);
                                    sendText = br.readLine();
                                    sBuffer.put(sendText.getBytes());
                                    sBuffer.flip();
                                    client.write(sBuffer);
                                } catch (IOException e) {
                                    e.printStackTrace();
                                    break;
                                }
                            }
                        }
                    }.start();
                }
                client.register(selector, SelectionKey.OP_READ);
            } else if (selectionKey.isReadable()) {
                client = (SocketChannel) selectionKey.channel();
                rBuffer.clear();
                count=client.read(rBuffer);
                if(count>0){
                    receiveText = new String( rBuffer.array(),0,count);
                    System.out.println(receiveText);
                    client = (SocketChannel) selectionKey.channel();
                    client.register(selector, SelectionKey.OP_READ);
                }
            }
        }
    
        public static void main(String args[]){
            NIOClient client = new NIOClient("192.168.120.67",1445);
            new Thread(client).start();
        }
    }
    

      

  • 相关阅读:
    mongoDB
    邮箱认证
    Django中开启事务的两种方式
    总结
    __new__和__init__和__call__方法理解
    jupyter
    text()和html()区别
    django模型中auto_now和auto_now_add的区别
    ajax嵌套陷阱
    模板内置函数(HTML)
  • 原文地址:https://www.cnblogs.com/weihuang6620/p/13858975.html
Copyright © 2020-2023  润新知