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();
    }
}

  

原文地址:https://www.cnblogs.com/weihuang6620/p/13858975.html