Я делаю простой сервер, который может обрабатывать текстовые команды в .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 строка.