Использование Stream Reader и Stream Writer в программировании TCP C # Вызывает пропущенные данные, обычно после пробелов - PullRequest
0 голосов
/ 05 апреля 2019

Я делаю простой сервер, который может обрабатывать текстовые команды в .NET 4.5. Всякий раз, когда передается большой сегмент, он обычно передается с большой частью, отсутствующей в кадре. Недостающая цель обычно приближается к пробелам.

например, если я передаю «Попытка соединения с сервером по IP-адресу:», обычно все, что будет передаваться, это «Попытка соединения». Однако, если я передаю «Попытка соединения для сохранения IP-адреса:», то весь кадр надежно передается.

Вот код цикла для клиентской стороны, где Client - это форма, а sr - StreamReader, а sw - StreamWriter для того же сокета. toSendToServer - это строка, которая передается между потоками и действует как буфер для отправки вещей.

        //main handling loop.
        Task<String> readVal = sr.ReadLineAsync();

        while(!Client.thisClient.IsDisposed && s.Connected){
            if (readVal.Status ==TaskStatus.RanToCompletion) {
                   String result = readVal.Result;
                   //printToConsole(result);
                   handleIncomingCommand(result.Split(' '));
                   readVal = sr.ReadLineAsync();
            }

            if (!toSendToServer.Equals("")) {
                sw.WriteLine(toSendToServer);
                sw.Flush();
                printToConsole(toSendToServer);
                toSendToServer = "";
            }
        }

метод printToConsole всегда и полностью печатает все, что должно быть напечатано, поэтому я знаю, что это не проблема безопасности потоков.

Вот мой код сервера:

        Task<String> readTask = reader.ReadLineAsync();
        //Main loop
        while (running && clientSocket.Connected)
        {
            Thread.Sleep(5);
            if (readTask.Status ==TaskStatus.RanToCompletion)
            {
                String result = readTask.Result;
                println(result);
                if(reader.Peek() != -1){
                    println("Buffer not cleared... Remaining buffer:");
                    println(reader.ReadLine());
                }
                if (result != null)
                {
                    String[] args = result.Split(' ');
                    Server.serverThread.sendCommand(username, args);
                }
                readTask = reader.ReadLineAsync();
            }
            if (toSend != null)
            {
                //.connect 131.212.37.205
                println("Sending \""+toSend+"\"");
                writer.Write(toSend);
                writer.Flush();
                toSend = null;
            }

        }

всякий раз, когда задача возвращается с результатом, она всегда обрезается (т. Е. При передаче «Попытка подключения к серверу по IP-адресу:» заставляет сервер печатать «Попытка подключения», а иногда даже просто «Попытка»). Ненадежно определять, что будет отправлено.

Почему некоторые данные теряются в потоке, и, кроме того, почему они всегда сосредоточены вокруг пробелов?

Я могу только предположить, что, поскольку читатель только читает до конца строки, что писатель должен каким-то образом сегментировать данные, предпочитая пробелы, однако, если бы это было так, то читатель все равно прочитал бы данные на следующем раунд цикла, но в этом случае на каждую передаваемую строку читается только 1 строка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...