c#并发和异步套接字连接
本文关键字:套接字 连接 异步 并发 | 更新日期: 2023-09-27 18:09:22
我正在研究一个简单的套接字服务器,它应该接受多个连接,并通过EndAccept()
将它们交给"连接"类。问题是,在接受连接后,代码不接受任何进一步的东西,直到连接结束。
我像这样在Main()
中创建套接字,然后通过Initialize()
将套接字传递给ServerEnvironment(静态类)。
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);
}
当我搜索这个问题时,我发现多线程可能是我的目的所必需的。然而,当我在Initialize();
和AddConnection();
中使用Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
时,出现了两个不同的线程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
调用被某些东西延迟了,可能是这里没有显示的代码。异步接受几乎总是没有意义的。不要盲目地抄袭糟糕的微软教程。你的accept循环应该是:
while (true) {
var socket = Accept();
StartProcessing(socket); //Cannot block!
}
。
可以使用Task
和await
来实现StartProcessing
。这使得异步套接字IO相当简单。或者,您可以为每个接收到的连接启动一个新任务/线程。
simple socket server
这样的事情不存在。您最好不要使用套接字,而使用现成的更高级的协议,如WCF或HTTP。