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

C#并发和异步套接字连接,c#,multithreading,sockets,asynchronous,C#,Multithreading,Sockets,Asynchronous,我正在使用一个简单的套接字服务器,该服务器应该接收多个连接,并通过EndAccept()将它们交给一个“connection”类。问题是,在接受一个连接后,在连接结束之前,代码不会接受任何进一步的内容 我像这样在Main()中创建套接字,然后通过Initialize()将套接字传递给ServerEnvironment(静态类) 一旦MainSocket被传递,ServerEnvironment将从那里接管 static Socket MainSocket; public static void

我正在使用一个简单的套接字服务器,该服务器应该接收多个连接,并通过
EndAccept()
将它们交给一个“connection”类。问题是,在接受一个连接后,在连接结束之前,代码不会接受任何进一步的内容

我像这样在
Main()
中创建套接字,然后通过
Initialize()
将套接字传递给ServerEnvironment(静态类)

一旦
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()中
添加连接(),两个不同的线程ID出现,所以我假设多线程已经是一种功能,我不需要手动创建线程。但这并不能解释我的问题

多线程对我来说是否有必要实现并发和异步套接字连接

编辑: 绑定错误..绑定到我的LAN地址,导致了一些问题

问题是,在接受连接后,在连接结束之前,代码不会再接受任何内容


这是因为下一个
beginacept
调用被延迟了,可能是因为这里没有显示代码。异步接受几乎总是毫无意义的。不要盲目复制糟糕的Microsoft教程。您的接受循环应该是:

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

您可以使用
Task
wait
实现
StartProcessing
。这使得异步套接字IO非常容易实现。或者,为接收到的每个连接启动一个新任务/线程

简单套接字服务器


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

如果您使用的是.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.
 }
但在.NET4.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.
 }

也许你应该看看,wich是一个非常容易使用的库。你使用的是.net>=4.5吗?“发生这种情况是因为下一个BeginAccept调用被延迟了,可能是因为这里没有显示的代码。”事实上,没有!我删除了程序本身的代码,它仍然挂起!太奇怪了。“每个收到的连接启动一个新任务/线程。”我不太了解套接字,但我知道在一定数量的连接上这是个坏主意。我之所以避免这样做是有原因的。我不能使用不同的协议,因为这是带有预先设计的协议的软件。关于Accept not Continue,您确定会有新的连接吗?无论如何,在任何情况下都应该切换到更简单的accept循环。这里没有理由使用async accept。所有不知道自己在做什么的人都会模仿别人。;关于线程,请确保只使用异步IO和wait-then。谷歌“.netsocketwait.”。;不管你做什么,放下APM模式。我绝对肯定连接没有被确认。此外,是否接受不阻止已存在的连接?否,这些连接应使用异步IO运行。他们使用独立的插座。接受的套接字未绑定到其“父”套接字。如果使用该故障保护测试代码无法接受两个连接,则不会有两个连接传入。所以我一定会尝试上面的方法,甚至是后面的方法,但是你介意向我解释一下为什么我的方法适用于其他应用程序吗?我查看了其他一些游戏套接字服务器,它们使用了我的确切模式。@Fuselight问题是,在再次调用
BeginAccept
之前,您无法打开新连接。因为这就是
beginacept
所做的,所以接受新的连接。我正在做的是启动一个线程来做工作,并立即调用
beginacept
。您的其他应用程序可能会工作,因为您正在做的“工作”完成得相当快。实际上,如果服务器要打开许多连接,您确实需要在用户连接后立即调用
Accept
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.
 }