TcpClient的VS插座asynchronousy打交道时 [英] TcpClient vs Socket when dealing with asynchronousy

查看:114
本文介绍了TcpClient的VS插座asynchronousy打交道时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是不是又一个的TcpClient VS插座。

This is not yet another TcpClient vs Socket.

TcpClient的是一个包装以防万一Socket类缓和的发展,也暴露出基础套接字。

TcpClient is a wrapper arround the Socket class to ease development, also exposing the underlying Socket.

还是......

在对的TcpClient类MSDN库页面,可以阅读以下说明:

On the MSDN library page for TcpClient class, one can read the following remark :

该TcpClient的类提供了连接,发送简单的方法,
  和接受过同步阻塞模式的网络数据流。

The TcpClient class provides simple methods for connecting, sending, and receiving stream data over a network in synchronous blocking mode.

和为Socket类:

Socket类允许您执行同步和
  使用任何的通信协议异步数据传输
  在ProtocolType枚举中列出。

The Socket class allows you to perform both synchronous and asynchronous data transfer using any of the communication protocols listed in the ProtocolType enumeration.

要发送/异步接收的一些数据仅通过,以GetStream一个呼叫要进行的TcpCient,检索底层的NetworkStream从/上数据可以读取/调用它ReadAsync和WriteAsync方法异步写,以下抽头模式(可能使用异步/等待结构)。

To send/receive some data asynchronously via the TcpCient only, a call to GetStream has to be made, to retrieve the underlying NetworkStream from/on which data can be read/write asynchronously by calling ReadAsync and WriteAsync methods on it, following the TAP pattern (potentially using async/await constructs).

要发送/通过socket异步接收的一些数据(我不是专家,但我认为这样做是正确),我们可以直接从/在Socket实例本身调用的BeginRead / EndRead BeginWrite / EndWrite读/写(或只是ReadAsync或WriteAsync ..不露出TAP模式 - 即不返回任务..混淆)

To send/receive some data asynchronously via the Socket (I am not expert but I think I got it right), we can directly read/write from/on the socket instance itself by calling BeginRead/EndRead BeginWrite/EndWrite (or just ReadAsync or WriteAsync .. not exposing the TAP pattern - i.e. not returning a Task .. confusing).

首先,任何想法,为什么在.NET 4.5中的Socket类不以任何方式实施抽头模式,即ReadAsync和WriteAsync返回任务(如果事件被称为不同,以preserve落后COMPAT)?

First of all, any idea why the Socket class in .NET 4.5 does not implement in any way the TAP pattern, i.e ReadAsync and WriteAsync returning Task (event if called differently to preserve backward compat) ?

总之,很容易搭建起APM模型方法对任务的方法,让我们说,我把这个异步方法(读)ReadAsyncTAP(返回任务)。

Anyway, easy enough to build a Task method from APM model method pair, so let's say I call this asynchronous method (for read) ReadAsyncTAP (returning a Task).

好吧?所以,现在,让我们说,我想code客户端的方法异步任务<字节[]> ReadNbBytes(INT nbBytes),我会从我的code调用异步从网络读取一定数量的字节。

Ok ? So now let's say I want to code a client method async Task<Byte[]> ReadNbBytes(int nbBytes) that I will call from my code to asynchronously Read a certain number of bytes from the Network.

仅在TcpClient的基于此方法的实施将通过调用GetStream得到的NetworkStream并将包含一个异步循环等候ReadAsync电话(S),直到缓冲区满。

The implementation of this method based exclusively on a TcpClient would get the NetworkStream by calling GetStream and will contain an asynchronous loop awaiting on ReadAsync call(s) until buffer full.

该方法的基础上,插座的实施将包含一个异步循环等候ReadAsyncTAP直到缓冲区满。

The implementation of this method based on the Socket would contain an asynchronous loop awaiting on ReadAsyncTAP until buffer full.

在这一天结束,从客户端code点,我想这没有什么区别。在这两种情况下,调用等待ReadNbBytes 将回归立即生效。不过,我想这是一个幕后区别...
对于TcpClient的,依靠的NetworkStream,并读出以某种方式阻止或不在任何点,比起直接使用插座的?如果不是在谈论同步阻塞模式时为TcpClient的这番话是错误的?

At the end of the day, from the client code point of view, I suppose it makes no difference. In both case, the call to await ReadNbBytes will 'return' immediately. However, I suppose it makes a difference behind the scenes ... For the TcpClient, relying on NetworkStream, does the reading somehow block or not at any point, compared to direct use of socket ? If not is the remark made for the TcpClient is wrong when talking about synchronous blocking mode ?

将大大pcited如果任何人都可以澄清AP $ P $!

Would be greatly apprecited If anyone could clarify !

感谢。

推荐答案

异步I / O不会阻塞。它看起来像MSDN文档是错误的(你可以按照反射验证这一点的的异步I / O调用的NetworkStream )。

Asynchronous I/O on TcpClient streams does not block. It looks like the MSDN docs are wrong (you can verify this in Reflector by following the NetworkStream's async I/O calls).

类型是有趣:默认情况下,基类将实现异步I / O阻塞同步I / O线程池线程。所以,你永远不要想对像一个异步I / O 的MemoryStream ,只提供同步的方法。

Stream types are "interesting": by default, the Stream base class will implement asynchronous I/O by blocking a thread pool thread on synchronous I/O. So you don't ever want to do asynchronous I/O on something like a MemoryStream, which only provides synchronous methods.

的NetworkStream 确实的提供异步I / O,所以异步I /开启o 的NetworkStream 情况下,实际上是异步的。但是,这并不总是这样:的FileStream 尤其是的通常的异步但如果你构建实例恰到好处它。

NetworkStream does provide asynchronous I/O, so asynchronous I/O on NetworkStream instances is actually asynchronous. But this is not always the case: FileStream in particular is usually not asynchronous but it is if you construct the instance just right.

至于为什么插座没有TAP方法:这是一个很好的问题!我认为这是一个疏忽,但现在.NET 4.5发布时,它看起来像它被排除故意的。这可能是因为他们只是不想过于复杂的API - 插座已经有同步和的两个的异步API的覆盖相同的操作集(的发送的SendTo 接收 ReceiveFrom 连接接受断开连接)。 TAP会进而要求为全套另外两个异步的API。这至少会引起一个有趣的命名状况( *异步名称已经采取,并且他们会增加两个 *异步对每个操作名称)。

Regarding why Socket doesn't have TAP methods: that is a very good question! I assumed it was an oversight, but now that .NET 4.5 is released, it looks like it was left out on purpose. It could be that they just don't want to overcomplicate the API - Socket already has synchronous and two asynchronous APIs covering the same set of operations (Send, SendTo, Receive, ReceiveFrom, Connect, Accept, Disconnect). TAP would in turn require two additional asynchronous APIs for that full set. That would at least cause an interesting naming situation (the *Async names are already taken, and they'd be adding two more *Async names for each operation).

附注:其他API是面向高性能异步插座通信。他们使用的SocketAsyncEventArgs ,这是不容易使用,但产生较少的内存垃圾。如果TAP的API添加到插座,他们希望以提供易于使用的版本(包装开始 / 结束)和性能更高的版本(包装异步)。

Side note: the "additional" APIs are for high-performance asynchronous Socket communication. They use SocketAsyncEventArgs, which is not as easy to use but produces less memory garbage. If TAP APIs were added to Socket, they would want to provide both the easy-to-use versions (wrapping Begin/End) and the higher-performance versions (wrapping Async).

如果你在做TAP方法插座有趣,一个很好的出发点是斯蒂芬Toub的的等待套接字操作(他只提供封装的高性能API)。我用我的异步 - 启用插座类似的东西。

If you're interesting in making TAP methods for Socket, a good starting point is Stephen Toub's Awaiting Socket Operations (he only provides wrappers for the high-performance API). I use something similar for my async-enabled sockets.

这篇关于TcpClient的VS插座asynchronousy打交道时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆