簡體   English   中英

C#並發和異步套接字連接

[英]C# Concurrent and Async Socket Connections

我正在研究一個簡單的套接字服務器,該服務器應該接受多個連接並通過EndAccept()EndAccept()給“連接”類。問題是在接受連接后,代碼不接受任何進一步的操作直到連接結束。

我在Main()創建套接字,然后通過Initialize()將套接字傳遞給ServerEnvironment(靜態類Initialize()

MainSocket.Bind(new IPEndPoint(IPAddress.Parse(Addr), Port));
MainSocket.Listen(10);

ServerEnvironment.Initialize(MainSocket);

while (true)
{
    Console.ReadLine();
    Console.WriteLine(">>");
}

一旦MainSocket通過,ServerEnvironment就會從那里接管。

static Socket MainSocket;

public static void Initialize(Socket _MainSocket)
{
    MainSocket = _MainSocket;

    AcceptGameConnection = new AsyncCallback(AddConnection);
    MainSocket.BeginAccept(AcceptGameConnection, null);
}

public static void AddConnection(IAsyncResult Result)
{
    Socket UserSocket = MainSocket.EndAccept(Result);
    ConnectionCount++;

    // Removed the stuff that happens to UserSocket because the same
    // symptoms occur regardless of their presence.

    MainSocket.BeginAccept(AcceptGameConnection, null);
 }

當我搜索這個問題時,我發現多線程可能是我的目的所必需的。 但是,當我使用Console.WriteLine(Thread.CurrentThread.ManagedThreadId); Initialize(); AddConnection(); ,出現兩個不同的線程ID,所以我假設多線程已經是一種功能,我不需要手動創建一個線程。 但這並不能解釋我的問題。

多線程是否需要我能夠擁有並發和異步套接字連接?

編輯:綁定錯誤..綁定到我的局域網地址,這導致一些問題。

如果您使用.net 4.0或更低版本,這就是您希望如何執行此操作

public static void Initialize(Socket _MainSocket)
{
    MainSocket = _MainSocket;

    AcceptGameConnection = new AsyncCallback(AddConnection);
    MainSocket.BeginAccept(result => {
        var userSocket = MainSocket.EndAccept(result);
        var thread = new Thread(AddConnection);
        thread.Start(userSocket);
        Initialize(MainSocket);
    }, null);
 }

 public static void AddConnection(IAsyncResult Result)
 {
     MainSocket.BeginAccept(AcceptGameConnection, null);
 }

 private static void AddConnection(Socket userSocket)
 {
     // Removed the stuff that happens to UserSocket because the same
     // symptoms occur regardless of their presence.
 }

但這就是你在.net 4.5或更高版本中的表現。

public static void Initialize(Socket mainSocket)
{           
    while(true)
    {
        var userSocket = await Task.Factory.FromAsync(
                                mainSocket.BeginAccept,
                                mainSocket.EndAccept);
        ThreadPool.QueueUserWorkItem(_ => AddConnection(userSocket));
    }
 }

 private static void AddConnection(Socket userSocket)
 {
     // Removed the stuff that happens to UserSocket because the same
     // symptoms occur regardless of their presence.
 }

問題是,在接受連接之后,代碼在連接結束之前不會接受任何進一步的操作。

發生這種情況是因為下一個BeginAccept調用被某些東西延遲,可能是這里未顯示的代碼。 異步接受幾乎總是毫無意義。 不要盲目地從可怕的微軟教程中復制。 你的接受循環應該是:

while (true) {
 var socket = Accept();
 StartProcessing(socket); //Cannot block!
}

就這樣。

您可以使用Taskawait實現StartProcessing 這使得異步套接字IO變得相當簡單。 或者,為每個連接啟動一個新任務/線程。

簡單套接字服務器

這樣的事情不存在。 您最好單獨留下套接字並使用現成的更高級別協議,例如WCF或HTTP。

暫無
暫無

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

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