创建可以同时处理并发请求的套接字

时间:2017-09-24 12:04:11

标签: c# sockets

假设以下代码:

Task.Run(()=>{
     while(true){
         Socket connection = socket.Accept(); // Problem
         Task.Run(()=> { //Receive from and Send to connection } )
     }
})

虽然它能够以多线程方式提供连接,但由于socket.Accept()在while循环中,因此所有请求都是一个接一个地提供,而不是以完全并发的方式提供。另一方面,它无法移动到内部任务中,因为在这种情况下,将创建无限(非常大且未知)的accept()个数。

这个问题的正确解决方案是什么?

示例:

 Connection A -- Accepted at 3:30:00:00 PM
 Connection B -- Accepted at 3:30:00:00 PM
 Instead of 
 Connection A -- Accepted at 3:30:00:00 PM
 Connection B -- Accepted at 3:30:00:50 PM

1 个答案:

答案 0 :(得分:1)

我认为这里可能会发生一些事情。不幸的是,我们没有看到你如何使用socket方法返回的accept对象 - 并且可能存在一些可能导致延迟的陷阱 - 但总的来说,它是不可能严格并行接受连接。

根据documentation

  

Accept同步提取第一个挂起的连接请求   从侦听套接字的连接请求队列,然后   创建并返回一个新的Socket。

因此,.NET保留(访问)来自底层操作系统的待处理请求队列(重要的是要注意该队列长度受操作系统限制)。根据TCP / IP的工作原理,一个套接字上一次只能提供一个客户端。因此,发生的情况是一个客户端连接,您调用accept并为该客户端创建一个新的TCP套接字,该端口由accept方法返回。这必然必须以连续的方式发生。 最初并行连接多个客户端的唯一方法是拥有多个侦听端口。