我正在尝试读取通过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);
}
}
请告诉我从机器上获取所有数据所缺少的内容。 提前谢谢..
答案 0 :(得分:21)
代码的问题在于,如果数据大小大于缓冲区大小(在您的情况下为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);
}
}
答案 1 :(得分:5)
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.");
}
答案 2 :(得分:2)
试试这段代码:
using (NetworkStream stream = client.GetStream())
{
do
{
Thread.Sleep(20);
} while (!stream.DataAvailable);
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(bytes));
}
} while (stream.DataAvailable);
}
}
希望这会有所帮助,它可以防止您错过任何发送给您的数据。
答案 3 :(得分:1)
试试这个:
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);
}
}
答案 4 :(得分:0)
TCP本身没有任何方法来定义&#34;数据结束&#34;条件。这是应用程序级别协议的责任。
例如,请参阅HTTP请求说明:
客户端请求(包含请求行的这种情况,只有一个标题字段)后跟一个空行,以便请求以双换行符结束
因此,对于请求,数据结束由两个换行序列决定。并回应:
Content-Type指定HTTP消息传送的数据的Internet媒体类型,而Content-Length指示其长度(以字节为单位)。
响应内容大小在数据前的标头中指定。 因此,您可以自行决定如何对一次传输的数据进行编码 - 它可以只是数据开头的前2或4个字节,只需要读取总大小或更复杂的方式。
答案 5 :(得分:0)
对于我的场景,消息本身告诉后续消息的长度。这是代码
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);
}
答案 6 :(得分:0)
加入这个问题有点晚了,但是我只是想问自己,什么是最整洁的方法。当协议未知时。 这是我的结论
先前答案中提到的while循环无法在NetworkStream上正常工作,它们会失败,并且您根本不会获得任何数据。
我还没有尝试过DataAvailable,也不知道它如何工作,所以我更喜欢任何人都可以理解的版本。
var ms = new MemoryStream();
byte[] data = new byte[1024];
int numBytesRead;
do
{
numBytesRead = stream.Read(data, 0, data.Length);
ms.Write(data, 0, numBytesRead);
} while (numBytesRead == data.Length);
var str = Encoding.ASCII.GetString(ms.ToArray());
答案 7 :(得分:0)
同步方法有时不显示请求正文。使用异步方法可以稳定地显示请求正文。
<script src="https://animejs.com/lib/anime.min.js"></script>
<div class="b-main">
<div class="b1"></div>
<div class="b2"></div>
<div class="b3"></div>
<div class="b4"></div>
</div>
答案 8 :(得分:0)
@George Chondrompilas答案是正确的,但是您可以使用CopyTo函数来完成此操作,而不必自己编写它: