[英]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!
}
就這樣。
您可以使用Task
和await
實現StartProcessing
。 這使得異步套接字IO變得相當簡單。 或者,為每個連接啟動一個新任務/線程。
簡單套接字服務器
這樣的事情不存在。 您最好單獨留下套接字並使用現成的更高級別協議,例如WCF或HTTP。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.