假设以下代码:
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
答案 0 :(得分:1)
我认为这里可能会发生一些事情。不幸的是,我们没有看到你如何使用socket
方法返回的accept
对象 - 并且可能存在一些可能导致延迟的陷阱 - 但总的来说,它是不可能严格并行接受连接。
Accept同步提取第一个挂起的连接请求 从侦听套接字的连接请求队列,然后 创建并返回一个新的Socket。
因此,.NET保留(访问)来自底层操作系统的待处理请求队列(重要的是要注意该队列长度受操作系统限制)。根据TCP / IP的工作原理,一个套接字上一次只能提供一个客户端。因此,发生的情况是一个客户端连接,您调用accept
并为该客户端创建一个新的TCP套接字,该端口由accept方法返回。这必然必须以连续的方式发生。 最初并行连接多个客户端的唯一方法是拥有多个侦听端口。