java - 使用套接字发送/接收压缩数据: how to properly receive the data sent from the client

标签 java sockets client-server chat datainputstream

我已经使用套接字开发了一个客户端-服务器聊天,它工作得很好,但是当我尝试使用 Deflate 压缩传输数据时,它不起作用:输出是“空”(实际上它不是空的,但我'下面会解释)。

压缩/解压部分100%工作(我已经测试过),所以问题肯定出在传输/接收部分的其他地方。

我使用以下方法将消息从客户端发送到服务器:

// streamOut is an instance of DataOutputStream
// message is a String

if (zip) { // zip is a boolean variable: true means that compression is active
    streamOut.write(Zip.compress(message)); // Zip.compress(String) returns a byte[] array of the compressed "message"
} else {
    // if compression isn't active, the client sends the not compressed message to the server (and this works great)
    streamOut.writeUTF(message);
}
streamOut.flush();

我使用这些其他方法接收从客户端到服务器的消息:

// streamIn is an instace of DataInputStream

if (server.zip) { // same as before: true = compression is active
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    byte[] buf = new byte[512];
    int n;

    while ((n = streamIn.read(buf)) > 0) {
        bos.write(buf, 0, n);
    }

    byte[] output = bos.toByteArray();
    System.out.println("output: " + Zip.decompress(output)); // Zip.decompress(byte[]) returns a String of decompressed byte[] array received
} else {
    System.out.println("output: " + streamIn.readUTF()); // this works great
}

调试一下我的程序,我发现 while 循环永远不会结束,所以:

byte[] output = bos.toByteArray();
System.out.println("output: " + Zip.decompress(output));

从未被调用过。

如果我将这两行代码放入 while 循环中(在 bos.write() 之后),那么一切正常(它打印从客户端发送的消息)!但我不认为这是解决方案,因为收到的 byte[] 数组的大小可能会有所不同。因此我认为问题出在接收部分(客户端实际上能够发送数据)。

所以我的问题变成了接收部分的 while 循环。我尝试过:

while ((n = streamIn.read(buf)) != -1) {

即使条件 != 0,但它和以前一样:循环永远不会结束,因此输出部分永远不会被调用。

最佳答案

-1仅在套接字关闭或损坏时返回。您可以在发送压缩内容后关闭套接字,然后您的代码将开始工作。但我怀疑您想保持套接字打开以接收更多( future )聊天消息。因此,您需要一些其他方式让客户端知道离散消息何时已完全传输。就像帕特里克建议的那样,您可以在每个压缩的有效负载之前传输消息长度。

不过,您也许可以利用 deflate 格式本身的某些内容。我认为它有一个流中最后一个 block 标记。如果您使用的是 java.util.zip.Inflater,请查看 Inflater.finished() .

关于java - 使用套接字发送/接收压缩数据: how to properly receive the data sent from the client,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11655486/

相关文章:

java - 无法将数据从 Java 客户端发送到 Python 服务器

python - 如何让服务器监听多个端口

java.util.InputMismatchException

java - Java中序列化JSON到JSON-LD的代码示例?

java - bufferedreader 和 filereader 的具体区别

java - 记录到文件并为每一行添加前缀的自定义打印流或打印编写器

java - 通过同一个套接字发送多条消息不起作用

java - 客户端-服务器基础设施中的 Applet

java - 无法从服务器传输 "get"流

java - 使用 Spring MVC 表单提交 portlet