【发布时间】:2012-08-12 10:40:48
【问题描述】:
这又不是另一个 TcpClient vs Socket。
TcpClient 是 Socket 类的一个包装器,用于简化开发,同时也暴露了底层的 Socket。
还是……
在 TcpClient 类的 MSDN 库页面上,可以阅读以下注释:
TcpClient 类提供了简单的连接、发送、 并以同步阻塞模式通过网络接收流数据。
对于 Socket 类:
Socket 类允许您执行同步和 使用任何通信协议的异步数据传输 在 ProtocolType 枚举中列出。
要仅通过 TcpCient 异步发送/接收某些数据,必须调用 GetStream,以检索底层 NetworkStream,通过调用 ReadAsync 和 WriteAsync 方法可以从其上异步读取/写入数据,如下TAP 模式(可能使用 async/await 结构)。
要通过 Socket 异步发送/接收一些数据(我不是专家,但我认为我做对了),我们可以通过调用 BeginRead/EndRead BeginWrite/EndWrite(或只是 ReadAsync 或 WriteAsync .. 不暴露 TAP 模式 - 即不返回 Task .. 令人困惑)。
首先,知道为什么 .NET 4.5 中的 Socket 类没有以任何方式实现 TAP 模式,即 ReadAsync 和 WriteAsync 返回 Task(如果以不同方式调用以保持向后兼容的事件)?
无论如何,从 APM 模型方法对构建一个 Task 方法很容易,所以假设我将此异步方法(用于读取)称为 ReadAsyncTAP(返回一个 Task)。
好的?所以现在假设我想编写一个客户端方法async Task<Byte[]> ReadNbBytes(int nbBytes),我将从我的代码中调用它以异步地从网络中读取一定数量的字节。
仅基于 TcpClient 的此方法的实现将通过调用 GetStream 获取 NetworkStream,并将包含一个异步循环等待 ReadAsync 调用,直到缓冲区满。
此方法基于 Socket 的实现将包含一个异步循环,等待 ReadAsyncTAP 直到缓冲区满。
归根结底,从客户端代码的角度来看,我想这没什么区别。在这两种情况下,对await ReadNbBytes 的调用都会立即“返回”。但是,我想这在幕后会有所不同...
对于依赖 NetworkStream 的 TcpClient,与直接使用 socket 相比,读取是否会在任何时候阻塞?如果不是,是不是说同步阻塞模式时对 TcpClient 的说明是错误的?
如果有人能澄清,将不胜感激!
谢谢。
【问题讨论】:
标签: c# sockets asynchronous tcpclient async-await