繁体   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