以下方法应该向服务器发送一些命令。它也应该作为字符串从服务器返回完整的回复。我遇到的问题是代码的回复部分;具体来说,我没有得到完整的回复。如果我在Console.WriteLine(bytesRead);
之前添加以下行memoryStream.Write(buffer,0,bytesRead);
,我会收到完整回复。似乎这个愚蠢的代码行有助于“暂停”某些东西,以便返回所有数据。我真的不知道我做错了什么,我需要你的帮助。感谢
public string Send(List<string> commands)
{
try
{
// String that will contain full reply from server
string fullServerReply = string.Empty;
TcpClient tcpClient = new TcpClient(host, port);
NetworkStream networkStream = tcpClient.GetStream();
foreach (string command in commands)
{
// Check to see if this NetworkStream is writable
if (networkStream.CanWrite)
{
// Translate the passed message into UTF8 and store it as a byte array.
byte[] sendBytes = Encoding.UTF8.GetBytes(command);
// Send the message to the connected TcpServer.
networkStream.Write(sendBytes, 0, sendBytes.Length);
}
else
{
// Close everything.
networkStream.Close();
tcpClient.Close();
return "";
}
// Check to see if this NetworkStream is readable
if (networkStream.CanRead)
{
using (MemoryStream memoryStream = new MemoryStream())
{
// Buffer to store the response bytes.
byte[] buffer = new byte[1024];
do
{
int bytesRead = networkStream.Read(buffer, 0, buffer.Length);
if (bytesRead <= 0)
{
break;
}
//Console.WriteLine(bytesRead); <- BY ADDING THIS CODE I GET THE FULL REPLY
memoryStream.Write(buffer, 0, bytesRead);
} while (networkStream.DataAvailable);
memoryStream.Position = 0;
fullServerReply += Encoding.UTF8.GetString(memoryStream.ToArray()); // THIS STRING DOES NOT CONTAIN FULL REPLY
}
}
else
{
// Close everything.
networkStream.Close();
tcpClient.Close();
return "";
}
}
// Close everything.
networkStream.Close();
tcpClient.Close();
return fullServerReply.Trim();
}
catch (ArgumentNullException ex)
{
return "";
}
catch (SocketException ex)
{
return "";
}
return "";
}
答案 0 :(得分:3)
烨! DataAvailable并不表示已收到完整的流。它仅指示接收缓冲区中是否有一些尚未准备好的数据。
当您添加console.readline时,您可以为网络数据包提供一个机会,以便在缓冲区中获取更多数据。
相反,你应该保持循环,直到网络流关闭,或者因为它是一个tcp流,无论你使用什么协议,它都会告诉你应用程序包有多大以便继续阅读。
答案 1 :(得分:2)
这就是网络的工作方式 - 你不能假设你立刻得到了所有东西,或者与写入的读取次数相同。在您的情况下,将写入添加到控制台就足够了以使客户端假脱机所有。
答案 2 :(得分:0)
尝试此操作以在循环后刷新对流的所有写入:
memoryStream.Flush();
memoryStream.Position = 0;
fullServerReply += Encoding.UTF8.GetString(memoryStream.ToArray()); // THIS STRING DOES NOT CONTAIN FULL REPLY