如何使用 UDP 或 TCP (lua / java) 发送压缩数据

Posted

技术标签:

【中文标题】如何使用 UDP 或 TCP (lua / java) 发送压缩数据【英文标题】:How to send compressed data using UDP or TCP (lua / java) 【发布时间】:2019-08-31 23:57:24 【问题描述】:

我正在制作一个带有 lua 客户端和 Java 服务器的服务器。 我需要压缩一些数据以减少数据流。

为了做到这一点,我使用 LibDeflate 在客户端压缩数据

local config = level = 1
local compressed = LibDeflate:CompressDeflate(data, config)
UDP.send("21107"..compressed..serverVehicleID) -- Send data

在服务器上我使用它来接收数据包(TCP)

out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new 
InputStreamReader(clientSocket.getInputStream(), "UTF-8"));
String inputLine;

while ((inputLine = in.readLine()) != null)  // Wait for data
    Log.debug(inputLine); // It is what get printed in the exemple
    String[] processedInput = processInput(inputLine);
    onDataReceived(processedInput);

我已经尝试使用 UDP 和 TCP 发送它,问题是一样的。 我尝试使用 LibDeflate:CompressDeflate 和 LibDeflate:CompressZlib 我尝试调整配置 没有任何效果:/

我希望收到一个包含整个字符串的数据包 但是我收到了几个包,每个包都包含压缩字符。例子(每一行都是服务器认为他收到了一个新的数据包): (来源:noelshack.com)

【问题讨论】:

需要在Java端解压数据。相反,您似乎正在尝试像读取文本一样读取压缩数据。 问题是我收到多行数据。 onDataReceived 函数为 1 个压缩数据包调用了大约 10 次,所以如果我尝试解压缩数据,它不起作用,因为我没有整个数据包,只有一部分 使用docs.oracle.com/javase/8/docs/api/java/util/zip/…。显然这不适用于UDP。为此,您需要小心地将数据包组装成一个字节数组,然后使用包装在 DeflaterInputStream 中的 ByteArrayInputStream 如果您不发送线路,为什么要尝试接收它们? @DavidSchwartz 我现在明白为什么它不起作用了 【参考方案1】:

经过大量研究,我终于设法解决了我的问题! 我用过这个:

DataInputStream in = new DataInputStream(new BufferedInputStream(clientSocket.getInputStream()));

int count;
byte[] buffer = new byte[8192]; // or 4096, or more

while ((count = in.read(buffer)) > 0) 
    String data = new String(buffer, 0, count);
    Do something...

我还没有测试收到的压缩字符串是否有效,我会在尝试时更新我的​​帖子。

编辑:它似乎工作

现在唯一的问题是当数据包大于缓冲区大小时我不知道该怎么办。 我想要在任何情况下都可以使用的东西,因为有些数据包比 8192 大,所以它们被切成两半。

【讨论】:

【参考方案2】:

假设客户端发送单个压缩“文档”,您的服务器端代码应如下所示(TCP 版本):

is = new DeflaterInputStream(clientSocket.getInputStream());
in = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String inputLine;

while ((inputLine = in.readLine()) != null)  
    ...

以上内容未经测试,还需要异常处理和代码以确保流始终关闭。

诀窍在于,您的输入管道需要在尝试将数据流作为文本行读取/处理之前对其进行解压缩。

【讨论】:

谢谢你的帮助,我刚试过,不幸的是同样的问题,但我想知道是不是lua在多个数据包中发送数据?? 编辑我的其他评论:不,我认为不是以多个数据包的形式发送数据的数据,因为当我发送未压缩的数据时,它工作正常。但是我注意到服务器和客户端都卡住了,直到我断开客户端与服务器的连接。一旦我这样做了,服务器就会收到压缩数据,就像帖子上的图片一样。

以上是关于如何使用 UDP 或 TCP (lua / java) 发送压缩数据的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 TCP 或 UDP 将数据从 Windows Phone 8.1 发送到 PC?

如何使用代码删除 tcp / udp 连接?

如何找出哪个进程正在侦听 Windows 上的 TCP 或 UDP 端口?

如何找出哪个进程正在侦听 Windows 上的 TCP 或 UDP 端口?

如何使用 Perl 通过 TCP 和 UDP 连接到远程机器?

ESP8266下载和刷固件(基于Lua脚本语言)