异步TCP套接字 - 澄清?

时间:2014-10-27 10:07:02

标签: .net sockets asynchronous tcpclient

  

异步不需要并行才能存在。   例如,在IO操作(web,硬盘操作......)时   可以释放当前线程,然后在IO操作之后释放   完成,通过完成端口,一个线程回来处理   结果

     

重点不在于阻挡。

我并不像套接字那么熟悉,但我已经阅读了很多。

但是当我读到异步套接字时,我看到的只是接受新连接的线程的例子,它正在打开一个新的后台线程来等待来自客户端的消息。

Like said here:

//  The meaning of "asynchronous" is that the socket operation, whether
//  it be a read, write, connect, or accept, happens in a background
//  thread and thus leaves your application free to do something
//  else while the socket operation is running.

来自MSDN:

  

异步套接字使用系统线程池中的线程   处理传入连接。 一个帖子负责接受   连接,另一个线程用于处理每个传入   连接,另一个线程负责从中接收数据   连接。这些可能是相同的线程,具体取决于哪个   线程由线程池分配。在以下示例中,   System.Threading.ManualResetEvent类暂停main的执行   执行可以继续时的线程和信号。

I also read Stephen Cleary's blog who mentioned the phases :

  • 构建
  • 绑定
  • 倾听 //< - 我的问题是什么
  • 接受
  • 正在连接
  • 阅读
  • 写作
  • 断开连接
  • 关闭
  • 结束

问题

观察聆听阶段 -

AFAIU,一个正在侦听的异步套接字 - 将绑定一个等待/阻塞的线程?

或者我完全错了,套接字可以"免费捆绑线程 - 等待"所以只有当有消息时,线程才会服务该操作。?

2 个答案:

答案 0 :(得分:0)

异步套接字操作利用了一种称为非阻塞IO的东西。以下是非阻塞IO行为:

  1. 如果一个线程使用“open_non_blocking”标志调用read,并且没有数据可用,那么该调用将返回“try_again”。
  2. 如果线程使用“open_non_blocking”标志调用write,并且输出缓冲区已满,则调用返回“try_again”。
  3. 此外,select()系统调用将非阻塞IO提升到下一级别。它构建在非阻塞IO之上,并将检查流准备就绪的任务卸载到驱动程序。要求驱动程序检查一组流是否准备就绪,并且它为每个流集返回调用线程的位掩码。位掩码向线程指示哪些流已准备就绪。这允许调用线程通过利用驱动程序返回的准备就绪信息,使用单个线程来复用许多活动流。应用程序服务器用于处理大量客户端的选择调用,以及针对高容量扩展的调用。 通过阻止应用程序线程选择操作,直到在一组文件描述符上发生某些事情(套接字表示为文件描述符)。那是什么东西?直到其中一个文件描述符准备好要读取或写入数据。通常,基于select()的应用程序服务器将执行以下操作:

    1. 使用要读取的文件描述符填充fd_set数据结构。
    2. 使用要写入的文件描述符填充fd_set数据结构。
    3. 调用select()。
    4. 网络驱动程序阻止呼叫,直到某事。
    5. 当其中一个文件描述符的状态发生变化时,网络驱动程序唤醒该线程,并返回该呼叫。
    6. 一旦select()返回,应用程序线程可以通过检查select()调用返回的每个文件描述符的位掩码来查找哪些文件描述符是可维护的。线程可以通过执行读取,写入或挂起来为就绪FD服务。
    7. 应用程序线程可以重复相同的过程。
    8. 在您的情况下,异步套接字框架利用select()调用,这允许它对文件描述符上的事件做出反应;虽然您的应用程序可以继续执行自己的工作,直到异步套接字框架完成读/写操作。

答案 1 :(得分:0)

您也可以查看this example。它显示了如何将TCP侦听器和所有客户端处理程序放入单个线程中。两者都实现为异步任务,因此允许异步运行它们。有关完整的工作示例,请参阅SingleSand.Samples.TcpServer.Server和SingleSand.Samples.TcpServer.Client。