2017-09-24 51 views
-2

假設下面的代碼:創建一個插口,可以同時服務的併發請求

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

雖然它能夠在一個多線程的方式提供服務的連接,所有的請求都提供了一個又一個,而不是在一個完全因爲socket.Accept()在while循環中,所以是併發方式。另一方面,它不能被轉移到內部任務中,因爲它將會創建一個無限的(非常大且未知的)數量。

這個問題的正確解決方案是什麼?

例子:

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

你應該有多個套接字來調用accept。 – VuVirt

+1

@VuVirt:多個套接字?那麼多少?不,這不是解決方案。一個愚蠢的人可以僞造這樣的事情。 – Arrrr

+0

你應該爲每個新的連接創建一個新的套接字,並保留原來的套接字來監聽新的連接 – mousetail

回答

1

我認爲可能有兩件事情會在這裏的。不幸的是,我們沒有看到你如何使用方法返回的socket對象 - 並且可能會有一些可能導致延遲的缺陷 - 但通常不可能嚴格地接受連接平行。

按照documentation

接受同步提取從偵聽套接字的連接請求隊列中的第一待連接請求 ,然後 創建並返回一個新的套接字。

因此,.NET保留(訪問)來自底層操作系統的掛起請求隊列(重要的是要注意該隊列長度受操作系統限制)。根據TCP/IP的工作原理,一次只能在一個套接字上提供一個客戶端。因此,發生的是一個客戶端連接,您調用accept,併爲該客戶端創建一個新的TCP套接字,該套接字由accept方法返回。這必然會以串行方式發生。 最初並行連接多個客戶端的唯一方法是擁有多個偵聽端口。

相關問題