简体   繁体   English

在异步回调中从 NetworkStream 读取缓冲区

[英]Read buffer from NetworkStream in async callback

See also Understand the NetworkStream.EndRead() example from MSDN .另请参阅了解 MSDN 中的 NetworkStream.EndRead() 示例

I'm trying to read asynchronously from a NetworkStream using the BeginRead and EndRead methods (specifically, I want to open a NetworkStream, do various other tasks, then process the data that's been received on the NetworkStream).我正在尝试使用BeginReadEndRead方法从 NetworkStream 异步读取(具体来说,我想打开一个 NetworkStream,执行各种其他任务,然后处理在 NetworkStream 上接收到的数据)。 The MSDN example for EndRead ( here ) has various issues and doesn't work as it stands, as noted in the linked question. EndRead的 MSDN 示例( 此处)存在各种问题,并且无法按原样工作,如链接问题中所述。 The answer to that question shows how the basic code should be structured, but it doesn't include the actual reading of the data from the NetworkStream in the callback.该问题的答案显示了基本代码的结构,但它不包括在回调中从 NetworkStream 实际读取数据。

In the callback function, how do I transfer the data that's been read from the NetworkStream into a buffer?在回调函数中,如何将从 NetworkStream 读取的数据传输到缓冲区?

EDIT编辑

This is the original MSDN example.这是原始的 MSDN 示例。

public static void myReadCallBack(IAsyncResult ar )
{
    NetworkStream myNetworkStream = (NetworkStream)ar.AsyncState;
    byte[] myReadBuffer = new byte[1024];
    String myCompleteMessage = "";
    int numberOfBytesRead;

    numberOfBytesRead = myNetworkStream.EndRead(ar);
    myCompleteMessage = String.Concat(myCompleteMessage,Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead));    

    // message received may be larger than buffer size so loop through until you have it all.
    while(myNetworkStream.DataAvailable)
    {
        myNetworkStream.BeginRead(myReadBuffer, 0, myReadBuffer.Length, new AsyncCallback(NetworkStream_ASync_Send_Receive.myReadCallBack), myNetworkStream);  
    }

    // Print out the received message to the console.
    Console.WriteLine("You received the following message : " + myCompleteMessage);
}

The basic problem with this example is that no data is transferred from the NetworkStream to myReadBuffer .这个例子的基本问题是没有数据从 NetworkStream 传输到myReadBuffer

EDIT 1编辑 1

Thanks to Dmytro Mukalov, the following code works:感谢 Dmytro Mukalov,以下代码有效:

internal class CallbackArgs
{
    public NetworkStream Stream { get; set; }
    public byte[] Buffer { get; set; }

    public CallbackArgs(NetworkStream stream, byte[] buffer)
    {
        Stream = stream;
        Buffer = buffer;
    }
}

//  In the caller:

    //  (Create and open thisNetworkStream, and check thisNetworkStream.CanRead)

    byte[] thisReadBuffer = new byte[1024];
    CallbackArgs args = new CallbackArgs(thisNetworkStream, thisReadBuffer);
    thisNetworkStream.BeginRead(thisReadBuffer, 0, thisReadBuffer.Length, new AsyncCallback(myReadCallBack), args);

//  The callback function:
public static void myReadCallBack(IAsyncResult ar)
{
    CallbackArgs args = (CallbackArgs)ar.AsyncState;
    NetworkStream myNetworkStream = args.Stream;
    byte[] myReadBuffer = args.Buffer;

    //  myReadBuffer now contains the data read from the network stream.

    int bytesRead = myNetworkStream.EndRead(ar);

    //  Do work on myReadBuffer, etc.
}

When callback is being executed, data is already transferred into a buffer passed to preceding BeginRead call.执行回调时,数据已传输到传递给前一个BeginRead调用的缓冲区中。 The problem with given example that it's trying to use local myReadBuffer buffer to read initial message.给定示例的问题是它试图使用本地myReadBuffer缓冲区来读取初始消息。 Instead you should make the buffer passed to BeginRead availaible for EndRead .相反,您应该使传递给BeginRead的缓冲区可用于EndRead You can do it by making it instance member of a class for this buffer, by passing it along with NetworkStream as state argument of BeginRead , using closure variable in some method which would initiate the reading loop, etc.您可以通过使其成为此缓冲区的类的实例成员,将其与NetworkStream作为BeginRead state参数一起传递,在某些方法中使用闭包变量来启动读取循环等来实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM