代码之家  ›  专栏  ›  技术社区  ›  Frerich Raabe

如何使套接字访问行为“异步”而不需要消息循环?

  •  1
  • Frerich Raabe  · 技术社区  · 16 年前

    我的程序使用 NetworkOutput

    class NetworkOutput
    {
    public:
      /* Constructs a NetworkOutput object; this constructor should not block, but it
       * should start attempting to the given host/port in the background.
       *
       * In case the connection gets closed for some reason, the object should immediately
       * try reconnecting.
       */
      NetworkOutput( const std::string &hostName, unsigned short port );
    
      /* Tells whether there is a remote client connected to this NetworkOutput object.
       * Clients can use this function to determine whether they need to both serializing
       * any data at all before calling the write() function below.
       */
      bool isConnected() const;
    
      /* Write data to the remote client, if any. In case this object is not connected
       * yet, the function should return immediately. Otherwise it should block until
       * all data has been written.
       *
       * This function must be thread-safe.
       */
      void write( const std::vector<char> &data );
    };
    

    现在,我已经使用非阻塞套接字实现了这一点。我不在家 网络输出 构造函数,我正在创建一个TCP套接字和一个内部帮助程序窗口。然后我做一个 WSAAsyncSelect WSAConnect . 这会立即返回,一旦连接成功,我的内部助手窗口的窗口过程就会得到通知。如果连接已关闭(因为远程客户端已离开),将调用消息过程,我将尝试重新连接。

    WSAAsyncSelect公司 呼叫似乎没有到达我的助手窗口。

    远程客户端 网络输出 类在调用之前不需要对复杂对象执行任何序列化工作 write() .

    2 回复  |  直到 16 年前
        1
  •  4
  •   Phil Devaney    16 年前

    你可以用 WSAEventSelect 而不是WSAASyncSelect,后者接受WSAEVENT的句柄而不是消息ID,然后使用 WSAWaitForMultipleEvents 等待事件发出信号。

    也可以使用用CreateEvent创建的普通Win32事件和 synchronisation 函数,如WaitForMultipleObjects。

        2
  •  0
  •   BenMorel Manish Pradhan    12 年前

    http://support.sas.com/documentation/onlinedoc/sasc/doc750/html/lr2/select.htm

    基本上,您可以指定一组要侦听的端口。
    当调用select时,它将取消线程的调度(从而允许其他线程在您执行非忙等待时工作)。您的线程在一个时间限制(通常是无限的)或一个信号(如果您想手动创建线程或系统这样做)后被唤醒,或者有一些输入需要在任何端口上处理。

    当你的线程醒来时,通常最好让另一个线程来处理工作;通常发生的情况是,为每个有数据等待读取的端口创建一个工作对象,并将这些对象添加到一个队列中,在该队列中,一组工作线程开始处理输入。完成后,再次调用select()以等待更多输入。

    注意:您不必这样做,它可以在一个线程中完成。