簡體   English   中英

套接字偵聽器多個同時的AcceptAsync調用

[英]Socket Listener Multiple Simultaneous AcceptAsync Calls

因此,我一直在研究套接字編程,並繼續閱讀創建高性能服務器的方法。

閱讀有關使用SocketAcceptAsync方法的信息,以及當連接立即可用時,有時調用如何同步執行(並返回false),以及如何在接受連接后使套接字回到監聽狀態,我開始想知道這是否意味着確實,盡管接受使用AcceptAsync的套接字的套接字將異步“等待”,但最終即使一次連接1000個客戶端,一次也只能處理1個新連接,具體取決於將客戶端傳遞給另一個線程的速度。處理,可能會限制性能。

然后,這使我想知道是否可以考慮使用所有連接使用SocketAsyncEventArgs的單個實例,而不是本來打算使用的對象池來編寫類。

我對此進行了更多思考,我想知道在這種情況下,如果在沒有可用連接的情況下進行多個AcceptAsync調用會發生什么情況。 因此,我制作了這個非常非常粗糙的測試應用程序,以了解會發生什么:

class Program
{
    private static Socket s;

    static void Main(string[] args)
    {
        s = new Socket(IPAddress.Any.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
        s.Bind(new IPEndPoint(IPAddress.Any, 10001));
        s.Listen(10);
        var e = new SocketAsyncEventArgs();
        e.Completed += EOnCompleted;
        s.AcceptAsync(e);
        e = new SocketAsyncEventArgs();
        e.Completed += EOnCompleted;
        s.AcceptAsync(e);
        e = new SocketAsyncEventArgs();
        e.Completed += EOnCompleted;
        s.AcceptAsync(e);
        e = new SocketAsyncEventArgs();
        e.Completed += EOnCompleted;
        s.AcceptAsync(e);
        while (true)
        {

        }
    }

    private static void EOnCompleted(object sender, SocketAsyncEventArgs socketAsyncEventArgs)
    {
        Console.WriteLine(socketAsyncEventArgs.AcceptSocket.RemoteEndPoint);
        Thread.Sleep(10000);
        var e = new SocketAsyncEventArgs();
        e.Completed += EOnCompleted;
        s.AcceptAsync(e);
    }
}

我使用了一個tcp測試應用程序來向應用程序發送帶有連接的垃圾郵件,結果表明,多個AcceptAsync調用創建了多個似乎並行執行的Accept / Complete周期。

我的問題是,這實際上有什么好處嗎? 這是允許更快處理傳入連接的合法方法嗎? 有什么缺點嗎?

編輯1:進一步研究這似乎在技術上是可能的,如果數據始終可用於異步調用的處理,則它們將全部同步運行,並且永不返回以接受新連接,或者至少會出現嚴重的延遲。

如果確實如此,如何生產高性能服務器?

通常,僅需要以下代碼:

while (true) {
 var socket = listener.Accept();
 Task.Run(async () => await RunConnectionAsync(socket));
}

此代碼的用戶模式部分將很快運行。 幾乎所有時間都將花費在內核上。 這將很快接受連接。 由於內核管理的積壓,不會刪除任何連接。

很少需要有多個未完成的接受呼叫來實現您的性能目標。 如果確實需要,只需在多個線程上運行相同的代碼即可。

SocketAsyncEventArgs API已過時。 基於任務的IO更加方便,並且占用大量CPU。

特別是,如果為每個操作創建一個新的SocketAsyncEventArgs ,則將失去該模式的所有好處。 那沒有意義。

在幾乎所有情況下,都不需要異步IO從套接字接受。 執行將花費更多的CPU時間,因此延遲會稍長一些。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM