0

我目前正在制作一个 C++ 应用程序(以改进我的 C++)。我正在创建一个套接字服务器,但我被卡住了。

我将如何在 C# 中做到这一点:

using System;
using System.Net;
using System.Net.Sockets;

namespace Network
{
    class HTcpListener
    {
        private Socket mSocket;

        public HTcpListener(int port)
        {
            IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, port);
            mSocket = new Socket(endpoint.AddressFamily, SocketType.Stream, ProtocolType.tcp);
            mSocket.Bind(endpoint);
            mSocket.Listen(10);
            mSocket.BeginAccept(new AsyncCallback(OnAccept));
        }

        private void OnAccept(IAsyncResult iAr)
        {
            // Handle connection and start up game

            mSocket.BeginAccept(new AsyncCallback(OnAccept));
        }
    }
}

但现在我想知道。在 WinSock2.h 中有一个名为 accept 的函数,但我想知道它是否与 BeginAccept 一样工作,如果不是,如何使它像我的 C# 示例中那样工作。它必须具有同时处理多个套接字的能力 + 1 个以上的套接字。

4

2 回答 2

1

我建议只accept()在工作线程上使用普通的阻塞调用来避免阻塞你的 UI 线程。它比处理异步套接字要简单得多。

但是如果你确实需要异步套接字,你应该使用这个ioctlsocket()函数来使你的套接字是非阻塞的。然后,accept()将立即返回错误WSAEWOULDBLOCK。然后,您可以使用该套接字作为调用的一部分select()WSAEventSelect()和/或WSAAsyncSelect()测试accept()调用是否已完成或一次等待多个套接字。

一旦其中一个类似select调用表明套接字已准备就绪,您就可以accept()再次调用套接字,并且它应该成功完成而不会阻塞。你完成了!

于 2013-10-29T23:09:14.033 回答
1

.NET 的异步套接字在后台使用的 API 是I/O Completion PortsAcceptEx和朋友的组合。这些通常用于需要高性能、可扩展 I/O 的应用程序中。与 .NET 包装器相比,它们的使用要复杂一些,但是如果您习惯了 .NET 的 APM 模式,那么您已经成功了一半。

Adam 建议使用非阻塞套接字也可以正常工作,只是可伸缩性显着降低。不过,不要让这阻止您检查它们,因为它们对于大多数应用程序来说已经足够好了,并且更容易移植到其他操作系统上可用的东西。

更以 C++ 为中心且完全可移植的方法是像Asio,它使用类似于 APM 的回调系统。强烈推荐它。

于 2013-10-30T01:23:40.600 回答