如何从NetworkStream获取所有数据
本文关键字:数据 获取 NetworkStream | 更新日期: 2023-09-27 18:24:33
我正在尝试读取通过TCP/IP
连接的机器缓冲区中的所有数据,但我不知道为什么我没有获得所有数据,有些数据正在丢失。这是我正在使用的代码。。
using (NetworkStream stream = client.GetStream())
{
byte[] data = new byte[1024];
int numBytesRead = stream.Read(data, 0, data.Length);
if (numBytesRead > 0)
{
string str= Encoding.ASCII.GetString(data, 0, numBytesRead);
}
}
请告诉我我缺了什么才能从机器上得到所有的数据。提前谢谢。。
代码的问题是,如果数据大小大于缓冲区大小(在您的情况下为1024字节),您将无法获得所有数据,因此您必须读取循环中的流。然后您可以Write
MemoryStream
中的所有数据,直到NetworkStream
结束。
string str;
using (NetworkStream stream = client.GetStream())
{
byte[] data = new byte[1024];
using (MemoryStream ms = new MemoryStream())
{
int numBytesRead ;
while ((numBytesRead = stream.Read(data, 0, data.Length)) > 0)
{
ms.Write(data, 0, numBytesRead);
}
str = Encoding.ASCII.GetString(ms.ToArray(), 0, (int)ms.Length);
}
}
MSDN中的这个例子:NetworkStream.DataAvailable显示了如何使用该属性来实现这一点:
// Examples for CanRead, Read, and DataAvailable.
// Check to see if this NetworkStream is readable.
if(myNetworkStream.CanRead)
{
byte[] myReadBuffer = new byte[1024];
StringBuilder myCompleteMessage = new StringBuilder();
int numberOfBytesRead = 0;
// Incoming message may be larger than the buffer size.
do{
numberOfBytesRead = myNetworkStream.Read(myReadBuffer, 0, myReadBuffer.Length);
myCompleteMessage.AppendFormat("{0}", Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead));
}
while(myNetworkStream.DataAvailable);
// Print out the received message to the console.
Console.WriteLine("You received the following message : " +
myCompleteMessage);
}
else
{
Console.WriteLine("Sorry. You cannot read from this NetworkStream.");
}
试试这个:
private string GetResponse(NetworkStream stream)
{
byte[] data = new byte[1024];
using (MemoryStream memoryStream = new MemoryStream())
{
do
{
stream.Read(data, 0, data.Length);
memoryStream.Write(data, 0, data.Length);
} while (stream.DataAvailable);
return Encoding.ASCII.GetString(memoryStream.ToArray(), 0, (int)memoryStream.Length);
}
}
试试这个代码:
using (NetworkStream stream = client.GetStream())
{
while (!stream.DataAvailable)
{
Thread.Sleep(20);
}
if (stream.DataAvailable && stream.CanRead)
{
Byte[] data = new Byte[1024];
List<byte> allData = new List<byte>();
do
{
int numBytesRead = stream.Read(data,0,data.Length);
if (numBytesRead == data.Length)
{
allData.AddRange(data);
}
else if (numBytesRead > 0)
{
allData.AddRange(data.Take(numBytesRead));
}
} while (stream.DataAvailable);
}
}
希望这有帮助,它应该可以防止您错过发送给您的任何数据。
同步方法有时不显示请求正文。使用异步方法可以稳定地显示请求体。
string request = default(string);
StringBuilder sb = new StringBuilder();
byte[] buffer = new byte[client.ReceiveBufferSize];
int bytesCount;
if (client.GetStream().CanRead)
{
do
{
bytesCount = client.GetStream().ReadAsync(buffer, 0, buffer.Length).Result;
sb.Append(Encoding.UTF8.GetString(buffer, 0, bytesCount));
}
while(client.GetStream().DataAvailable);
request = sb.ToString();
}
TCP本身并没有任何方法来定义"数据结束"条件。这是应用程序级portocol的责任。
例如,请参阅HTTP请求描述:
客户端请求(在这种情况下由请求行和只有一个标题字段组成)后面跟着一个空行,因此请求以双换行结束
因此,对于请求,数据的末尾由两个换行序列决定。回应:
Content Type指定HTTP消息传输的数据的Internet媒体类型,而Content Length表示其长度(以字节为单位)。
响应内容大小在数据之前的标头中指定。因此,如何对一次传输的数据量进行编码取决于您——它可以是数据开始时的前2或4个字节,可以是要读取的总大小,也可以是更复杂的方式(如果需要)。
对于我的场景,消息本身告诉了后续消息的长度。这是代码
int lengthOfMessage=1024;
string message = "";
using (MemoryStream ms = new MemoryStream())
{
int numBytesRead;
while ((numBytesRead = memStream.Read(MessageBytes, 0, lengthOfMessage)) > 0)
{
lengthOfMessage = lengthOfMessage - numBytesRead;
ms.Write(MessageBytes, 0, numBytesRead);
}
message = Encoding.ASCII.GetString(ms.ToArray(), 0, (int)ms.Length);
}
@George Chondrompilas答案是正确的,但您可以使用CopyTo函数,而不是自己编写:
https://stackoverflow.com/a/65188160/4120180