美文网首页
Java 粘包和半包问题

Java 粘包和半包问题

作者: hemiao3000 | 来源:发表于2022-09-15 15:49 被阅读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);

相关文章

  • 2.Netty基本--TCP粘包半包如何解决,协议和序列化到底啥

    [toc] 1.什么是TCP粘包和半包?为什么会出现粘包和半包? 粘包: 粘包半包 混合双打: 首先TCP是可靠有...

  • Netty 半包,粘包处理

    基于TCP协议处理网络数据经常面对半包和粘包问题,那么什么是半包问题,什么是粘包问题呢?应用层消息在被发送到网络之...

  • Netty处理半包粘包的解码思路

    Netty处理半包粘包的解码思路 前言 写netty通讯的都不免遇到半包粘包情况。那么半包粘包是什么意思呢?我们可...

  • Netty粘包/半包问题

    在netty中经常会出现粘包/半包问题? 1.应用程序写入的数据大于套接字缓冲区大小, 这将导致半包现象2.应用程...

  • TCP 半包粘包问题

    什么是粘包现象 TCP 粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着...

  • 即时通讯

    iOS即时通讯,从入门到“放弃”?socket的半包,粘包与分包的问题iOS 处理socket粘包问题iOS___...

  • 粘包、半包

    1.什么是粘包? 粘包通常出现在TCP的协议里面,对于UDP来说是不会出现粘包状况的。通俗的讲,就是在发包的时候会...

  • netty的编解码

    什么是拆包/粘包 TCP 粘包/拆包 半包:读取的数据不是一个数据包粘包:读取的数据超过一个数据包 粘包问题的解决...

  • 使用TCP收发消息需要处理的常见问题

    要实现服务器和客户端之间完整的收发消息,需要处理以下的几个问题。 粘包半包问题 粘包就是一次从socket缓冲区中...

  • 关于Socket 粘包和半包的处理

    前段时间在开发即时通讯,使用的是CocoaAsyncSocket 遇到了几个常见的问题,网上说的关于粘包和半包其实...

网友评论

      本文标题:Java 粘包和半包问题

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