C#NetworkStream.Read()是否会等待读取指定数量的数据?
在C/C++中,常规非阻塞网络套接字上的read()将立即返回缓冲区中当前可用的数据量,达到指定的量(因此,如果我们请求16个字节,而此时只有8个可用字节,那么我们将得到这8个字节,由我们再次调用read()并获取所有数据)C#NetworkStream.Read()是否会等待读取指定数量的数据?,c#,networking,C#,Networking,在C/C++中,常规非阻塞网络套接字上的read()将立即返回缓冲区中当前可用的数据量,达到指定的量(因此,如果我们请求16个字节,而此时只有8个可用字节,那么我们将得到这8个字节,由我们再次调用read()并获取所有数据) 在C#中有一个NetworkStream,它具有内置超时-这是否意味着NetworkStream.Read()会等待,直到达到超时或读取请求的数据量,或者它会为我们提供缓冲区中当前可用的大于0的数据量,直到请求的数据量为止(就像标准套接字那样)即使还有时间?它也将读取参数中
在C#中有一个NetworkStream,它具有内置超时-这是否意味着NetworkStream.Read()会等待,直到达到超时或读取请求的数据量,或者它会为我们提供缓冲区中当前可用的大于0的数据量,直到请求的数据量为止(就像标准套接字那样)即使还有时间?它也将读取参数中指定字节数的可用数据,如所述,除非流通过超时或其他异常关闭 读取操作读取尽可能多的可用数据,最大读取量为size参数指定的字节数。如果远程主机关闭连接,并且已收到所有可用数据,则读取方法立即完成并返回零字节 我是这样解决的:
byte[] TotalData = new byte[0];
byte[] TempData = new byte[0];
using (TcpClient TCPClient = new TcpClient())
{
try
{
TCPClient.Connect(somehost, someport);
}
catch (Exception eee)
{
// Report the connection failed in some way if necessary
}
if (TCPClient.Connected)
{
using (NetworkStream clientStream = TCPClient.GetStream())
{
// You can reduce the size of the array if you know
// the data received is going to be small,
// don't forget to change it a little down too
byte[] TCPBuffer = new byte[524288];
int bytesRead = 0;
int loop = 0;
// Wait for data to begin coming in for up to 20 secs
while (!clientStream.DataAvailable && loop< 2000)
{
loop++;
Thread.Sleep(10);
}
// Keep reading until nothing comes for over 1 sec
while (clientStream.DataAvailable)
{
bytesRead = 0;
try
{
bytesRead = clientStream.Read(TCPBuffer, 0, 524288);
Array.Resize(ref TempData, bytesRead);
Array.Copy(TCPBuffer, TempData, bytesRead);
// Add data to TotalData
TotalData = JoinArrays(TotalData, TempData);
}
catch
{
break;
}
if (bytesRead == 0)
break;
Thread.Sleep(1000);
}
}
}
}
安全的方法是使用MemoryStream,它将确保等待并将所有流读取到内存中,然后您可以随意使用它
public void SaveUserTemplate(Stream stream)
{
MemoryStream memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
memoryStream.Position = 0;
byte[] templatePathLength = new byte[4];
memoryStream.Read(templatePathLength, 0, templatePathLength.Length);
int nBytesTemplatePathLength = BitConverter.ToInt32(templatePathLength,0);
....
CopyTo函数最后调用此函数:
但是,如果仍然有时间(从调用stream.read()
public void SaveUserTemplate(Stream stream)
{
MemoryStream memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
memoryStream.Position = 0;
byte[] templatePathLength = new byte[4];
memoryStream.Read(templatePathLength, 0, templatePathLength.Length);
int nBytesTemplatePathLength = BitConverter.ToInt32(templatePathLength,0);
....
private void InternalCopyTo(Stream destination, int bufferSize)
{
Contract.Requires(destination != null);
Contract.Requires(CanRead);
Contract.Requires(destination.CanWrite);
Contract.Requires(bufferSize > 0);
byte[] buffer = new byte[bufferSize];
int read;
while ((read = Read(buffer, 0, buffer.Length)) != 0)
destination.Write(buffer, 0, read);
}