这不是另一个 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 模型方法对构建任务方法很容易,所以假设我将此异步方法(用于读取)称为 ReadAsyncTAP(返回任务)。
好 ?所以现在假设我想编写一个客户端方法async Task<Byte[]> ReadNbBytes(int nbBytes)
,我将从我的代码中调用该方法以异步地从网络中读取一定数量的字节。
此方法的实现仅基于 TcpClient 将通过调用 GetStream 获取 NetworkStream 并将包含一个异步循环等待 ReadAsync 调用,直到缓冲区满。
这个基于 Socket 的方法的实现将包含一个异步循环,等待 ReadAsyncTAP 直到缓冲区满。
归根结底,从客户端代码的角度来看,我想这没有什么区别。在这两种情况下,调用await ReadNbBytes
都会立即“返回”。但是,我想这在幕后会有所不同......对于依赖 NetworkStream 的 TcpClient,与直接使用套接字相比,读取是否在任何时候都会阻塞?如果不是,在谈论同步阻塞模式时,对 TcpClient 的评论是错误的吗?
如果有人能澄清,将不胜感激!
谢谢。