2

TCP/IP ソケットを介して通信する Mono ベースの C# クライアントと Python サーバーを使用するプログラムがあります。メッセージはほとんどバイナリ形式を使用しますが、通常、各メッセージの大部分は埋め込まれた UTF-8 文字列 (英語) です。各メッセージは通常短い (100 バイト未満) ですが、一部は長くなります (最大 64K)。大量のデータが交換されるため、送信時にデータを圧縮することで、メッセージ サイズと帯域幅の使用量を削減したいと考えています。

私の最初の調査では、2 つの標準ライブラリ間で明らかに互換性があるものは見つかりませんでした。Python にはzlibライブラリがありますが、C# のDeflateStreamまたは GZipStream を使用できません (利用できない外部 DLL が必要なため)、SharpZipLib の ZipOutputStream では動作しないようです (「エラー -3 - 正しくないヘッダー" 応答)。(Mono を使用していない人はもっと運がいいかもしれません。以下の Duncan の回答を参照してください。)

この通信リンクを介して圧縮を有効にする簡単な方法について聞きたいと思います。ある言語で簡単に実装できるソリューションは、他の言語でも同等のものが必要であることを念頭に置いてください。バイトストリーム全体を圧縮することをお勧めしますが、バイナリメッセージではなくUTF-8文字列に特化したソリューションを受け入れます。

理想的には外部依存を最小限に抑えたいのですが、それは現実的ではないかもしれません。

更新: SharpZipLib を試してみたところ、Python のデコード側で繰り返しエラーが発生したため、特定の言語の圧縮ライブラリの提案だけでなく、機能することが知られているコードを使用して具体的な提案を行うことができました。

4

4 に答える 4

3

あなたが書いた:

同様に、どちらの標準ライブラリも gzip 圧縮を提供しますが、Python はこの場合 file を使用することを想定しているため、実用的ではありません。

それは実際には真実ではありません。Python のgzip.GZipFile()クラスは、filenameまたは のいずれかを取りますfileobjStringIO文字列を使用する場合は、オブジェクトを次のように使用します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 の BZip2 と Python のライブラリが役に立ちました。私がテストした内容と方法は次のとおりです。

まず、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

*nixシステムを使用しているようです。その場合、他のすべての方法が失敗した場合は、システムライブラリ(Mono.Unix.Native)を使用するだけで、適切な.Netライブラリを見つけることを心配する必要はありません。

于 2012-05-06T18:15:23.907 に答える
0

過去に .net に zlib を使用したことがあり、マネージド ソリューションを提供するためにネイティブ zlib ライブラリをラップするライブラリもあります。私はあなたがやっていることと似たようなことをする必要がありました. 小さな転送の場合はメモリ内で直接圧縮を行い、ファイルに圧縮してからURLからファイルをダウンロードし、ファイルから解凍してはるかに大きなファイルにします。

于 2012-05-04T11:42:14.833 に答える