Данные TCP иногда поступают в неправильном порядке и являются неполными

Я создал приложение TCP Server на Java и клиентское приложение на С#. Когда я отправляю данные, клиент иногда получает данные не по порядку, а иногда части полностью отсутствуют. В основном код, который я использую на сервере (java), выглядит так (раздетый):

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

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

Я использую "\n" в качестве разделителя. На стороне клиента (С#) я использую следующий код:

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"

Однако я получаю (иногда) следующее: «5_8_61» и «_LEVELDATA»

Другой пример: "5_4_1" и "6_LEVELDATA" приводят к одной строке: "5_6_LEVELDATA"

Это похоже на небольшую проблему, но на самом деле это в значительной степени разрушает мое приложение. Я прочитал много сообщений, но единственные ответы, которые я прочитал, это либо «это не должно происходить с TCP», либо «сначала отправьте длину сообщения tcp», что в данном случае никак не поможет, потому что проблема не Данные не разбиваются на несколько пакетов, они просто не поступают в правильном порядке, что и должен делать TCP.

Я на 100% уверен, что строка всегда завершена до того, как она будет отправлена ​​приложением Java.

Мне действительно интересно, что я делаю неправильно здесь. Что-то не так в моем коде? Буду признателен за любую помощь с этой проблемой. Заранее спасибо.


person Sennohej    schedule 27.09.2012    source источник
comment
Ненавижу это говорить, но этого не должно происходить с TCP. Что вы видите, просматривая сетевой трафик с помощью Wireshark? Вы используете несколько потоков?   -  person CodeCaster    schedule 27.09.2012
comment
это может быть несколько вещей, лучше всего, как сказал CodeCaster, проверить с помощью wireshark. Также вы не указываете свою кодировку в java, а в C # вы читаете int.   -  person JIV    schedule 27.09.2012
comment
Пробовали ли вы читать строки с помощью метода ReadLine StreamReader вместо того, чтобы использовать свой собственный?   -  person L.B    schedule 27.09.2012
comment
Да, у меня есть. Вместо этого я написал собственный метод ReadLine, чтобы сообщения tcp не разбивались на несколько пакетов с помощью разделителя. Использование метода ReadLine() StreamReader дает те же результаты.   -  person Sennohej    schedule 27.09.2012
comment
Теперь я также попробовал Wireshark. Он показывает те же недостатки: данные перепутаны.   -  person Sennohej    schedule 27.09.2012
comment
Похоже, ты попал в точку, CodeCaster. На самом деле это была проблема с потоками. Спасибо вам всем!   -  person Sennohej    schedule 27.09.2012


Ответы (1)


После попытки Wireshark оказалось, что моя проблема существует на сервере. По-видимому, каждое TCP-сообщение было отправлено в отдельном потоке. Спасибо за все ваши комментарии! Моя проблема теперь решена.

person Sennohej    schedule 27.09.2012
comment
Другими словами, никогда не существовало такой вещи, как «правильный порядок». - person user207421; 28.09.2012