4

別の Vala 問題が発生しました。UDP 経由でデータを送受信しようとしています。送信が機能し、Wireshark を介して、サーバーが期待される結果を送信していることがわかります。問題は次のとおりです。私のプログラムはデータを取得しません。

確認したところ、UDP データを送信するためのソケットが作成されている場合、特定のポートが開いたままになっていることがわかります。これは、PC がこれらの ICMP メッセージをサーバーに送信しないため、Wireshark によって確認されます。

私がこれまでに得たもの:

try
{
    SocketClient mySocket = new SocketClient();
    mySocket.protocol = SocketProtocol.UDP;
    mySocket.type = SocketType.DATAGRAM;
    var conn = mySocket.connect (new InetSocketAddress(addr,targetPort));
    conn.output_stream.write(themessage_in_a_uint8_array);
    DataInputStream response = new DataInputStream (conn.input_stream);
    string resp ="";
    char myChar;
    try
    {
        do
        {
            myChar = (char)response.read_byte();
            print ("Response" + myChar.to_string());
        }while(true);
    }
    catch(Error e)
    {
        print(e.message);
    }
}
catch(Error e)
{print(e.message);}

現在何が起こっているか: メッセージが送信され、文字列 'Response' がコンソールに 1 回出力され、その後ループします。

私がチェックするresponse.get_available()と、0が返されます。

確認できlsof | grep used_portnumberますが、確かに、使用済みのソケットは開いたままです。私は何を間違っていますか?

4

1 に答える 1

1

よくわかりませんが、これが私が疑うことです。

UDPはデータグラムプロトコルです(データは明示的にデータに切り刻まれます)。サーバーは1つのデータグラムをクライアントに送信しました。現在、BSDソケット(およびその後のあらゆる場所)では、下にあるソケットがデータグラムタイプである場合、readパケット全体を読み取ります。バッファの長さが不十分な場合、メッセージは切り捨てられます。

解は1バイトで読み取られます。例えば

uint8[] buffer = new uint8[1 << 16]; // Maximum UDP length - we don't loose anything
unowned string locale;
bool need_convert = GLib.get_charset (out locale);
do {
    ssize_t len = response.read (buffer);
    string text;
    if (need_convert) {
        text = GLib.convert ((string)buffer, len, locale, "UTF-8");
    } else {
        text = (string)buffer;
    }
    stdout.print("Response " + text);
} while (true);

編集現在のロケールが「UTF-8」ベースであると想定せずに、UTF-8テキストを印刷するようにコードを変更しました。

PS 1これは、私の頭に浮かぶBSDソケット(Winsocketとこれに基づくすべてのもの)の1つの落とし穴であるため、私の推測です。質問がより具体的になる場合(つまり、質問に対する答えではない場合)は、優雅に対応してください。

PS 2一般的に、バイトと文字を混在させないことをお勧めします。ASCII互換のエンコーディング(ISO、UTF-8)では、文字のASCIIサブセットを送信しても安全ですが、CJKエンコーディングを試行した場合、または送信者がUTF-8で「ą」を送信し、送信者がISO-8859として処理する場合は噛み付きます- 2(この文字のエンコーディングが異なる場合)。おもちゃの例だけだと思います。そうでない場合は、すべてのプログラマーがテキストを操作するためのエンコーディングと文字セットについて積極的に知っておく必要があることを読みたいと思うかもしれません。

于 2012-12-25T00:58:31.107 に答える