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,因此我假设多线程已经是一种功能,我不需要手动创建线程。但这并不能解释我的问题。

是多线程必要的,我能够有并发和异步套接字连接?

编辑:绑定错误,绑定到我的局域网地址,导致一些问题

c#并发和异步套接字连接

如果你使用的是。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!
}

可以使用Taskawait来实现StartProcessing。这使得异步套接字IO相当简单。或者,您可以为每个接收到的连接启动一个新任务/线程。

simple socket server

这样的事情不存在。您最好不要使用套接字,而使用现成的更高级的协议,如WCF或HTTP。