在什么情况下一个的NetworkStream没有一次读取所有的数据? [英] Under what conditions does a NetworkStream not read in all the data at once?
问题描述
在回调 NetworkStream.BeginRead
我似乎注意到所有字节总是读。我看到很多教程检查,看看是否读取动作小于总字节数,如果是这样,请再次阅读,但是这似乎永远是这样。
In the callback for NetworkStream.BeginRead
I seem to notice that all bytes are always read. I see many tutorials check to see if the BytesRead is less than the total bytes and if so, read again, but this never seems to be the case.
条件若(读取动作< totalBytes)
从来没有火,即使大量的数据被发送一次(几千个字符),甚至如果缓冲区大小设定为一个非常小的值(16左右)。
The condition if (bytesRead < totalBytes)
never fires, even if a lot of data is sent at once (thousands of characters) and even if the buffer size is set to a very small value (16 or so).
我还没有与'老办法',因为我用的不是调用NetworkStream.BeginRead,并提供一个回调,我叫EndRead Task.Factory.FromAsync测试这一点。或许任务自动包含不返回,直到所有的数据被读取这个功能?我不知道。
I have not tested this with the 'old-fashioned way' as I am using Task.Factory.FromAsync instead of calling NetworkStream.BeginRead and providing a callback where I call EndRead. Perhaps Tasks automatically include this functionality of not returning until all data is read? I'm not sure.
无论哪种方式,我仍然好奇,当所有的数据将不会被立刻读取。是它甚至需要检查如果不是所有的数据被读出,并且如果是的话,再次读?我似乎无法获得有条件永远运行。
Either way, I am still curious as to when all data would not be read at once. Is it even required to check if not all data was read, and if so, read again? I cannot seem to get the conditional to ever run.
感谢。
推荐答案
尝试通过慢速链路上发送数据的兆字节。为什么会流要等到它的所有的存在给调用者的任何过呢?如果什么对方没有关闭连接。 - 存在的是的所有数据在该点没有概念
Try sending megabytes of data over a slow link. Why would the stream want to wait until it was all there before giving the caller any of it? What if the other side hadn't closed the connection - there is no concept of "all the data" at that point.
假设你开到另一台服务器和呼叫的BeginRead
(或读
)有较大的缓冲的连接,但它只发送100字节,那么等待你的答复 - 你会期望的NetworkStream
办?不要给你的数据,因为你给它太大的缓冲?这将是非常适得其反。
Suppose you open a connection to another server and call BeginRead
(or Read
) with a large buffer, but it only sends 100 bytes, then waits for your reply - what would you expect NetworkStream
to do? Never give you the data, because you gave it too big a buffer? That would be highly counterproductive.
您应该的绝对的不承担任何物流(与的MemoryStream
的有争议的除外),将填补你给它的缓冲区。这有可能是的FileStream
始终将本地文件,但我的期望的难道不是为共享文件。
You should absolutely not assume that any stream (with the arguable exception of MemoryStream
) will fill the buffer you give it. It's possible that FileStream
always will for local files, but I'd expect it not to for shared files.
编辑:样品code这显示了缓冲区没有填充 - 发送HTTP 1.1请求(相当糟糕:)
Sample code which shows the buffer not being filled - making an HTTP 1.1 request (fairly badly :)
// Please note: this isn't nice code, and it's not meant to be. It's just quick
// and dirty to demonstrate the point.
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
class Test
{
static byte[] buffer;
static void Main(string[] arg)
{
TcpClient client = new TcpClient("www.yoda.arachsys.com", 80);
NetworkStream stream = client.GetStream();
string text = "GET / HTTP/1.1\r\nHost: yoda.arachsys.com:80\r\n" +
"Content-Length: 0\r\n\r\n";
byte[] bytes = Encoding.ASCII.GetBytes(text);
stream.Write(bytes, 0, bytes.Length);
stream.Flush();
buffer = new byte[1024 * 1024];
stream.BeginRead(buffer, 0, buffer.Length, ReadCallback, stream);
Console.ReadLine();
}
static void ReadCallback(IAsyncResult ar)
{
Stream stream = (Stream) ar.AsyncState;
int bytesRead = stream.EndRead(ar);
Console.WriteLine(bytesRead);
Console.WriteLine("Asynchronous read:");
Console.WriteLine(Encoding.ASCII.GetString(buffer, 0, bytesRead));
string text = "Bad request\r\n";
byte[] bytes = Encoding.ASCII.GetBytes(text);
stream.Write(bytes, 0, bytes.Length);
stream.Flush();
Console.WriteLine();
Console.WriteLine("Synchronous:");
StreamReader reader = new StreamReader(stream);
Console.WriteLine(reader.ReadToEnd());
}
}
这篇关于在什么情况下一个的NetworkStream没有一次读取所有的数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!