0

ソケット技術を使用して、pc で実行されている C# プログラム (サーバー) から python クライアント スクリプト (Linux マシンで実行されている) に 2 つの整数を送信しようとしています。今までは文字列を送ることができました。

サーバ:

TcpListener listener = new TcpListener(IPAddress.Any, 12345);
Invoke(new PrintMsg(printMsg), new object[] { "Trying to connect" });
listener.Start();

for(; ; ;)
{
   TcpClient client = null;

   try
   {
      client = listener.AcceptTcpClient();
      netStream = client.GetStream();
      Invoke(new PrintMsg(printMsg), new object[] { "Found client" });


      //send command to client
      ASCIIEncoding encoder = new ASCIIEncoding();
      byte[] buffer = encoder.GetBytes("Hello client");
      netStream.Write(buffer, 0, buffer.Length);
      netStream.Flush();

   }

   catch (Exception ex)
   {
      Invoke(new PrintMsg(printMsg), new object[] { ex.ToString() });
   }
}

クライアントコードは次のとおりです。

while True:
    msg = s.recv(1024)
    print 'SERVER:', msg

したがって、バッファ配列に整数を「入れて」、それを python スクリプトに送信したいと思います。出来ますか?私は何を間違っていますか?

4

2 に答える 2

2

「整数を送信するにはどうすればよいか」という問題に到達する前に、「メッセージを送信するにはどうすればよいか」というより大きな問題を解決する必要があります。

TCP では、send一方の側で呼び出すと、バッファ全体を一度に送信したとしても (これは保証されません)、もう一方の側はrecv一度にすべてではなく、複数の個別の呼び出しでデータを取得する場合があります。さらに悪いことに、単一sendの の一部と次の一部を取得することがあります。sendrecv

これを処理する上位レベルのプロトコル (ZeroMQ や HTTP など) を使用できます。ただし、生の TCP を使用したいだけの場合は、自分で処理する必要があります。

明らかな解決策の 1 つは、改行 (または NUL バイトなど) のような区切り記号です。ただし、もちろん、メッセージの途中で改行をエスケープする何らかの方法が必要です。もう 1 つの可能性は、 netstringのように、メッセージの残りの部分を説明する何らかの種類のヘッダーを使用することです。または、JSON などの自己区切りメッセージ タイプを使用できます。

デリミタの問題を処理する多くの非常に単純な方法は、整数の送信を自動的に処理します。JSON には数値が型として含まれます。または、ネット文字列または改行で区切られた文字列を介して整数を文字列として送信することもできます。

数値を「バイナリ」の方法でエンコードしたい場合は、表現を選択し、両側でその表現との間で変換するコードを記述する必要があります。たとえば、物事を 32 ビットの符号付き整数に制限し、それらをビッグ エンディアンの C 整数形式で送信する場合、そのための Python コードはbuf = struct.pack('!I', number)およびnumber = struct.unpack('!I', buf).

ただし、バイナリ形式が必要かどうかを検討する必要があります。人間として読んでデバッグするのは明らかに難しいです。また、間違えやすくなります (たとえば、エンディアンやワード サイズを忘れるなど)。そして、それを行う簡単な方法は限られています (たとえば、!I上記の形式は、約 20 億を超える数では失敗します)。また、必ずしもよりコンパクトであるとは限りません。多くの場合、改行を含む文字列として 2 ~ 3 バイト、バイナリ形式では 4 バイトの小さな数値を大量に送信します。

行ベースの数値リーダーの単純な Python 実装を次に示します。

def read_numbers_off_socket(s):
    buf = ''
    while True:
        newbuf = s.recv(4096)
        if not newbuf:
            yield int(buf)
            break
        buf += newbuf
        lines = buf.split('\n')
        for line in lines[:-1]:
            yield int(line)

しかし、次のようにすると、さらに簡単に実行できますs.makefile

def read_numbers_off_socket(s):
    with s.makefile() as f:
        for line in f:
            yield int(line)
于 2013-02-27T21:13:27.297 に答える
2

TCP 接続の確立に使用したクライアント ライブラリの種類をクライアント コードから判断するのは困難です。

ZeroMQ など、C# と Python をサポートするメッセージ キューの実装を使用しないのはなぜですか? データ構造の受け渡しをさらに複雑にする必要がある場合は、メモリ内のキーと値のストア ソリューションを使用して、Redis などのキューを実装することも検討できます。利点は、メッセージ キュー サーバー/クライアントの実装が適切に設計されており、ビジネス ロジックで送信/受信するコードを 1 行または 2 行作成するだけでよいことです。

于 2013-02-27T21:06:13.420 に答える