在什么情况下一个的NetworkStream没有一次读取所有的数据? [英] Under what conditions does a NetworkStream not read in all the data at once?

查看:1034
本文介绍了在什么情况下一个的NetworkStream没有一次读取所有的数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在回调 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆