美文网首页
2021-03-17

2021-03-17

作者: hemiao3000 | 来源:发表于2021-03-17 15:47 被阅读0次
    
        /**
         * 从 buf 中查找 "\r\n",并返回这段(包括 \r\n)空间的长度。
         * 如果 buf 中没有,则返回 0 。
         */
        private static int findLineEnd(final byte[] buf, int rlen) {
            int splitbyte = 0;
            while (splitbyte + 1 < rlen) {
                if (buf[splitbyte] == '\r' && buf[splitbyte + 1] == '\n' && splitbyte + 1 < rlen) {
                    return splitbyte + 2;
                }
                splitbyte++;
            }
            return 0;
        }
    
        /**
         * 半包、粘包问题解决:
         *      从 InputStream 中找一行数据并返回。“一行”的标志是截止到 \r\n,不包括 \r\n 。
         */
        private static String readLine(InputStream inputStream) throws IOException, RuntimeException {
            int splitbyte = 0;
            int rlen = 0;
            byte[] buf = new byte[BUFSIZE];
            int read = -1;
            inputStream.mark(BUFSIZE);
            try {
                read = inputStream.read(buf, 0, BUFSIZE);
            } catch (Exception e) {
                throw new SocketException("Could not Read");
            }
    
            if (read == -1) {
                throw new SocketException("Could not Read");
            }
    
            /* buf 中存储的数据区间为: buf[0] ... buf[read-1],共 read 个字节。 */
    
            while (read > 0) {
                rlen += read;
                splitbyte = findLineEnd(buf, rlen);
                if (splitbyte > 0) {
                    break;
                }
    
                read = inputStream.read(buf, rlen, BUFSIZE - rlen);
            }
    
            /* buf 中存储的数据区间为: buf[0] ... buf[splitbyte-1],共 splitbyte 个字节。其中包含 \r\n 在内。*/
    
            // -2 的目的是返回的结果内容中不包含 \r\n 。
            return new String(buf, 0, splitbyte - 2);
        }
    
        private static void safeClose(Closeable closeable) {
            try {
                if (closeable != null) {
                    closeable.close();
                }
            } catch (IOException e) {
                System.out.println("Could not close: " + e.getMessage());
            }
        }
    
        private static void safeClose(Socket socket) {
            try {
                if (socket != null && !socket.isClosed()) {
                    socket.close();
                }
            } catch (IOException e) {
                throw new IllegalArgumentException("Cloud not close socket: " + e.getMessage());
            }
        }
    
        private static void safeClose(ServerSocket serverSocket) {
            try {
                if (serverSocket != null && !serverSocket.isClosed()) {
                    serverSocket.close();
                }
            } catch (IOException e) {
                throw new IllegalArgumentException("Cloud not close socket: " + e.getMessage());
            }
    
        }
    

    测试:

     String message = "hello world\r\ngoodbye";
     byte[] bytes = message.getBytes(StandardCharsets.UTF_8);
     //System.out.println(findLineEnd(bytes, bytes.length));
    
    InputStream stream = new ByteArrayInputStream(bytes);
    
    String line = readLine(stream);
    
    System.out.println(line);
    

    相关文章

      网友评论

          本文标题:2021-03-17

          本文链接:https://www.haomeiwen.com/subject/uzlecltx.html