3

Java で TCP サーバー アプリケーションを作成し、C# でクライアント アプリケーションを作成しました。データを送信しているときに、クライアントがデータを順不同で受信したり、一部が完全に欠落したりすることがあります。基本的に、サーバー(Java)で使用するコードは次のようになります(削除されています):

ServerSocket welcomeSocket = new ServerSocket(port);
Socket connectionSocket = welcomeSocket.accept();

outputStream = new DataOutputStream(socket.getOutputStream()); //Create stream
outputStream.writeBytes(message + "\n");
outputStream.flush();

区切り文字として「\n」を使用します。クライアント側 (C#) では、次のコードを使用します。

private const char Delimiter = '\n';

tcpclnt = new TcpClient();
tcpclnt.NoDelay = true;
tcpclnt.Client.DontFragment = true;
tcpclnt.Connect(ip, port);

//This function is executed in a separate thread
public void Receive() 
{
try
{
    stream = tcpclnt.GetStream();
    streamreader = new StreamReader(stream);
    this.Connected = true;
    while (Connected)
    {
        string line = ReadLine(streamreader);
        Console.WriteLine("Received data: " + line);
    }
}
}

private string ReadLine(StreamReader reader)
{
    bool finished = false;
    string line = "";

    while (finished == false)
    {
        int asciiNumber = reader.Read();
        char character = Convert.ToChar(asciiNumber);

        if (!character.Equals(Delimiter))
            line += character;
        else finished = true;
    }

    return line;
}

コードはそれほど複雑ではありません。ただし、サーバーから送信されたデータがクライアントで正しく受信されるとは限りません。例として、「5_8_1」と「6_LEVELDATA」の 2 つの文字列を受け取る必要があります。

ただし、(時々)得られるのは、「5_8_61」と「_LEVELDATA」です

別の例: "5_4_1" と "6_LEVELDATA" は、1 つの文字列 "5_6_LEVELDATA" になります。

これは小さな問題のように思えますが、実際には私のアプリケーションをかなり台無しにしてしまいます。私は多くの投稿を読みましたが、私が読んだ唯一の答えは、「これはTCPでは起こらないはずです」または「TCPメッセージの長さを最初に送信する」のいずれかです。データが複数のパッケージに分割されているのではなく、正しい順序で到着していないだけです。これは、TCP が行うべきことです。

Java アプリケーションによって送信される前に、文字列が常に完全であると 100% 確信しています。

私はここで何が間違っているのだろうか。私のコードで何かが台無しになっていますか? この問題について何か助けていただければ幸いです。前もって感謝します。

4

1 に答える 1

3

Wireshark を試してみたところ、サーバーに問題があったようです。明らかに、すべての TCP メッセージは別のスレッドで送信されました。コメントありがとうございます!私の問題は解決しました。

于 2012-09-27T14:38:29.093 に答える