TCP Server工具类,BIO阻塞和非阻塞NIO

启动自定义代码的方式

WebServer Initialized Event

	//@Component

	//ApplicationContext context 注入

    //@PostConstruct
    //@Async

    @EventListener(ApplicationReadyEvent.class)
    @Component
    public class TcpServerListener implements ApplicationListener<WebServerInitializedEvent> {
   

        @Override
        public void onApplicationEvent(WebServerInitializedEvent event) {
   
            //int serverPort = event.getWebServer().getPort();
            // 在此处添加代码以创建和启动 TCP 服务器
            updateServer.startServer(8082);
        }
    }

ServerSocket

基本代码

            // 创建ServerSocket并绑定端口
            ServerSocket serverSocket = new ServerSocket(8080);

            // 启动一个新线程来接受客户端连接
                while (true) {
   
                    try {
   
                        // 接受客户端连接
                        Socket clientSocket = serverSocket.accept();

                        // 关闭客户端连接
                        clientSocket.close();
                    } catch (IOException e) {
   
                        e.printStackTrace();
                    }
                }

DataInputStream

	@PostConstruct
    @Async
    public void startServer() throws Exception {
   
        //开启TCP Server
        ServerSocket serverSocket = new ServerSocket(8082);
        log.info("服务端打开了 Server started on port {}", 8082);
        while (true) {
   
            //等待连接
            Socket socket = serverSocket.accept();

            //获取 输入流
            DataInputStream inputStream = new DataInputStream(socket.getInputStream());

            DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
            log.info("服务端收到了连接:Accepted connection from client: {}", socket.getInetAddress());
            
            //读取的字节数
            byte[] buffer = new byte[380];//1024
            //真正读取到了多少个
            int bytesRead;
            //循环进行读取
            while ((bytesRead = inputStream.read(buffer)) != -1) {
   
                //处理二进制数据
                processBinaryData(buffer, bytesRead, socket, outputStream);
            }//循环读取,正常每次都会读取完毕

            inputStream.close();
            outputStream.close();
            socket.close();
            
            
        }//死循环接收连接
    }//初始化方法结束*/

    //关闭输入流
    //socket.shutdownInput();
    //关闭输出流,关闭 Socket
    //socket.shutdownOutput();
    //关闭Socket
    //socket.close();

InputStreamReader 字符流

  • BufferedReader(new InputStreamReader(socket.getInputStream()))
  • new PrintWriter(socket.getOutputStream(), true)
public class TcpServer {
   
    public static void main(String[] args) {
   
        try {
   
            //连接
            ServerSocket serverSocket = new ServerSocket(5555);
            System.out.println("服务器启动,等待客户端连接...");

            //阻塞
            Socket socket = serverSocket.accept();
            System.out.println("客户端已连接.");

            //创建 输入流。读取
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //创建 输出流。写入
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);

            String message = in.readLine();
            System.out.println("收到客户端消息:" + message);
            // 解析 JSON 消息

            // 发送响应给客户端
            out.println("构建响应 JSON");

            // 关闭连接
            socket.close();
            serverSocket.close();
        } catch (IOException e) {
   
            e.printStackTrace();
        }
    }
}

NIO Selector

ServerSocketChannel

@Configuration
public class TcpServerConfig {
   
    //@Value("${tcp.ip}")
    //private String tcpIp;

    //ApplicationContext context
    //@PostConstruct
    //@Async
    @EventListener(ApplicationReadyEvent.class)
    public void startServer() {
   // throws IOException
        //异步执行
        //ThreadUtil.execAsync(() -> {
   
        try {
   
            
            //1.打开选择器
            Selector selector = Selector.open();
            //2.打开通道 serverSocketChannel
            ServerSocketChannel channel = ServerSocketChannel.open();
            //3.设置非阻塞
            channel.configureBlocking(false);
            //4.绑定本机IP
            channel.bind(new InetSocketAddress(tcpIp, 8082));
            //5.进行注册
            channel.register(selector, SelectionKey.OP_ACCEPT);
            log.info("===============Server started on port 8082===================");

            while (true) {
   
                //6.选择通道
                int readyChannels = selector.select();
                //校验下
                if (readyChannels == 0) {
   
                    continue;
                }
                //7.获取所有的key
                Set<SelectionKey> selectedKeys = selector.selectedKeys();
                //8.获取迭代器
                Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
                //如果存在
                while (keyIterator.hasNext()) {
   
                    //9.获取这个key
                    SelectionKey key = keyIterator.next();
                    //10.如果是个连接
                    if (key.isAcceptable()) {
   
                        //11.接收这个通道
                        SocketChannel clientSocketChannel = serverSocketChannel.accept();
                        //12.非阻塞的
                        clientSocketChannel.configureBlocking(false);
                        //13.注册为可读
                        clientSocketChannel.register(selector, SelectionKey.OP_READ);
                        log.info("收到连接:Accepted connection from: {}", clientSocketChannel.getRemoteAddress());
                        
                    } else if (key.isReadable()) {
   
                        //14.如果是可读,获取通道
                        SocketChannel clientSocketChannel = (SocketChannel) key.channel();
                        //读取数量
                        ByteBuffer buffer = ByteBuffer.allocate(38);//1024
                        //15.真实读取到了多少个
                        int bytesRead = -1;
                        try {
   
                            //这里报错了,增加防护,如果没防护,这个nio就断了
                            bytesRead = clientSocketChannel.read(buffer);
                        } catch (Exception e) {
   
                            log.info("未读取到");
                            e.printStackTrace();
                        }
                        //未读取到 关闭
                        if (bytesRead == -1) {
   
                            clientSocketChannel.close();
                        } else if (bytesRead > 0) {
    //读到的 > 0
                            //读取到了
                            buffer.flip();
                            //读到这个字节里
                            byte[] data = new byte[bytesRead];
                            buffer.get(data);
                            //处理逻辑
                            processBinaryData(data, bytesRead, clientSocketChannel);
                            //String message = new String(data).trim();
                            //System.out.println("Received message: " + message);

                            //清理
                            buffer.clear();
                        }//读到了
                    }//是可读的
                    //移除key
                    keyIterator.remove();
                }//如果存在
            }//死循环
        } catch (Exception e) {
   
            e.printStackTrace();
        }
        //}, "MyTcpServerThread").start();
}
    //有错误,往外层抛
    private void sendUpdateMessage(SocketChannel clientSocketChannel) {
   
        //转为byte
        byte[] binaryData = hexStringToBytes("dfsfsdfdsaf");
        
        //1.申请字节
        ByteBuffer buffer = ByteBuffer.allocate(binaryData.length);
        //2.放入
        buffer.put(binaryData);
        //3. 快速翻阅,浏览
        buffer.flip();
        //3.循环是否有:剩下的,遗留的;尚未使用、解决的
        while (buffer.hasRemaining()) {
   
            try {
   
                //进行写入
                clientSocketChannel.write(buffer);
                log.info("发送了一次升级的消息");
            } catch (IOException e) {
   
                log.info("发送升级失败");
                e.printStackTrace();
            }
        }
    }

相关推荐

  1. TCP Server工具BIO阻塞阻塞NIO

    2024-02-08 08:48:03       27 阅读
  2. NIO阻塞模式

    2024-02-08 08:48:03       12 阅读
  3. Verilog 14: 阻塞阻塞赋值的异同

    2024-02-08 08:48:03       27 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-08 08:48:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-08 08:48:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-08 08:48:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-08 08:48:03       18 阅读

热门阅读

  1. 347. 前 K 个高频元素

    2024-02-08 08:48:03       30 阅读
  2. 【大数据面试题】004 Flink状态后端是什么

    2024-02-08 08:48:03       31 阅读
  3. 【Vue项目】filters过滤器

    2024-02-08 08:48:03       27 阅读
  4. List与数组相互转换

    2024-02-08 08:48:03       32 阅读
  5. 突破编程_C++_面试(基础知识(8))

    2024-02-08 08:48:03       29 阅读
  6. C语言:矩阵中的最小元素

    2024-02-08 08:48:03       27 阅读
  7. 51 单片机入门 400 例

    2024-02-08 08:48:03       26 阅读
  8. LeetCode 第28天

    2024-02-08 08:48:03       32 阅读
  9. 12.Swift字典

    2024-02-08 08:48:03       24 阅读