2

我有一个带有基于 Mono 的 C# 客户端和 Python 服务器的程序,它们通过 TCP/IP 套接字进行通信。消息主要使用二进制格式,但每条消息的最大部分通常是嵌入的 UTF-8 字符串(英文)。每条消息通常都很短(不到 100 字节),但有些消息可能更长(最多 64K)。交换了大量数据,我想通过在传输数据时压缩数据来减少消息大小和带宽使用。

我最初的研究没有发现任何明显兼容这两个标准库的东西。Python 有一个zlib库,但我不能使用 C# 的DeflateStream或 GZipStream(因为它们需要一个我没有可用的外部 DLL),而且它似乎不适用于 SharpZipLib 的 ZipOutputStream(发出“错误 -3 - 不正确标头”响应)。(那些不使用 Mono 的人可能会有更多的运气 - 请参阅下面的 Duncan 的回答。)

我有兴趣了解在此通信链路上启用压缩的简单方法,请记住,任何可能易于用一种语言实现的解决方案都需要在另一种语言中具有等价物。我会接受专门针对 UTF-8 字符串而不是二进制消息的解决方案,尽管首选是压缩整个字节流。

理想情况下,我希望将外部依赖项保持在最低限度,但我意识到这可能不切实际。

更新:在尝试使用 SharpZipLib 并在 Python 解码方面遇到重复错误后,我真的可以使用已知有效的代码提出具体建议,而不仅仅是针对一种语言或另一种语言的压缩库的建议。

4

4 回答 4

3

你写了:

同样,两个标准库都提供 gzip 压缩,但 Python 期望在这种情况下使用文件,这是不切实际的。

事实并非如此。Python 的gzip.GZipFile()类采用 afilename或 a fileobj。如果你想使用一个字符串,只需使用一个StringIO对象作为fileobj

from gzip import GzipFile
from StringIO import StringIO
sio = StringIO()
with GzipFile(fileobj=sio, mode='wb') as gzip:
    gzip.write('uncompressed data')
compressed = sio.getvalue()
于 2012-05-04T13:30:27.163 回答
2

SharpZipLib 和 Python 库中的 BZip2 对我有用。这是我测试的内容和方法:

一、C#程序(引用SharpZipLib):

using System;
using ICSharpCode.SharpZipLib.BZip2;
using System.IO;

namespace Test
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            var fStream = new FileStream("/home/konrad/output.bin", FileMode.Create);
            using(var writer = new StreamWriter(new BZip2OutputStream(fStream)))
            {
                for(var i = 0; i < 10; i++)
                {
                    writer.WriteLine("Line no {0}.", i);
                }
            }
        }
    }

}

然后是 Python:

from bz2 import BZ2File
import sys

f = BZ2File("/home/konrad/output.bin")
for line in f.readlines():
    sys.stdout.write(line)

接下来,运行 C# 程序。在那之后:

$ python ctest.py
Line no 0.
Line no 1.
Line no 2.
Line no 3.
Line no 4.
Line no 5.
Line no 6.
Line no 7.
Line no 8.
Line no 9.

我认为它也可以反过来工作。

于 2012-05-06T21:04:56.957 回答
0

我过去曾将 zlib 用于 .net,还有一些库包装了原生 zlib 库以提供托管解决方案。我需要做一些类似于你正在做的事情。我会直接在内存中进行压缩以进行较小的传输,然后压缩到文件中,然后从 url 下载文件并从文件中解压缩以获得更大的文件。

于 2012-05-04T11:42:14.833 回答
0

看来您使用的是 *nix 系统。如果是这种情况并且所有其他方法都失败了,您可以简单地使用系统库 (Mono.Unix.Native) 而无需担心找到合适的 .Net 库。

于 2012-05-06T18:15:23.907 回答