从NetworkStream调用BeginRead

时间:2011-11-10 17:17:33

标签: c# network-programming networkstream

好的我想连接到Socket并使用System.Net.Sockets.NetworkStream类读取网络流。这就是我到目前为止所做的:

NetworkStream myNetworkStream;
Socket socket;

socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, 
    ProtocolType.IPv4);
socket.Connect(IPAddress.Parse("8.8.8.8"), 8888);

myNetworkStream = new NetworkStream(socket);

byte[] buffer = new byte[1024];
int offset = 0;
int count = 1024;

myNetworkStream.BeginRead(buffer, offset, count, ??, ??);

现在我需要一个AsyncCallback和一个Object state来完成我的BeginRead方法,但我甚至不确定这是否会起作用。我此时有点失落!我需要从哪里离开?

1 个答案:

答案 0 :(得分:13)

基本上,当您在异步操作上调用Begin*方法时,需要调用相应的End*语句(有关更多详细信息,请参阅Asynchronous Programming Overview on MSDN,具体而言标题为“结束异步操作”的部分。)

那就是说,你通常想传递一个方法/匿名方法/ lambda表达式,它会做一两件事:

1)调用相应的End*方法,在本例中为Stream.EndRead。调用时此调用不会阻塞,因为在操作完成之前不会调用callback(请注意,如果在异步调用期间发生异常,则在调用End*方法时将抛出此异常)。

2)可能会启动一个新的异步调用。在这种情况下,假设您想要阅读更多数据,因此您应该开始对Stream.BeginRead进行新的调用

假设您想要做#2,您可以执行以下操作:

// Declare the callback.  Need to do that so that
// the closure captures it.
AsyncCallback callback = null;

// Assign the callback.
callback = ar => { 
    // Call EndRead.
    int bytesRead = myNetworkStream.EndRead(ar);

    // Process the bytes here.


    // Determine if you want to read again.  If not, return.
    if (!notMoreToRead) return;

    // Read again.  This callback will be called again.
    myNetworkStream.BeginRead(buffer, offset, count, callback, null);
};

// Trigger the initial read.
myNetworkStream.BeginRead(buffer, offset, count, callback, null);

但是,如果您使用的是.NET 4.0,使用FromAsync method上的TaskFactory class可以更轻松。