从NetworkStream调用BeginRead

5

好的,我想要连接到一个 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
你走错了方向。请使用MSDN库中的示例代码来使用Socket.BeginReceive()函数。 - Hans Passant
你有使用异步版本的理由吗?你不能只使用Read()吗? - svick
这样行吗?最终我想让它成为一个持续运行的服务,但现在我只想看到一些结果。同时,谢谢Hans,我会去看看的。 - JMK
1个回答

16

基本上,当您对异步操作调用Begin*方法时,需要调用相应的End*语句(有关更详细的信息,请参见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方法TaskFactory上轻松实现该功能。


如果你使用的是.NET Framework 4.5+或.NET Standard/Core,你可以在一个async方法中使用Stream.ReadAsync - GGG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接