【问题标题】:Asynchronous socket questions异步套接字问题
【发布时间】:2011-03-07 21:26:39
【问题描述】:

好的,我在this 问题中发现轮询套接字无法扩展,所以我决定研究异步套接字,我有几个问题。

  1. 如果我有数百个客户都试图向他们的合作伙伴发送数据,那么最好使用什么异步方法? select() poll() 还是我可以在非阻塞套接字上调用 recv() ?
  2. 当我轮询并发现有数据要读取时,我是否应该生成一个线程来处理它?
  3. 我应该担心任何睡眠功能,还是应该让程序占用 100% 的 CPU?
  4. 将整个功能放入一个类中是否有效?我真的很想做这样的事情:

//thread 1:  
while(!quit){  
   manager.check_clients();  
   manager.handle_clients();  
   manager.display_clients();  
 }
//thread 2:
while(!quit)
  manager.manage_admin_input();

【问题讨论】:

  • 谢谢乔恩,出于某种原因,我把自己的冒号删掉了。

标签: c++ sockets select asynchronous


【解决方案1】:

轮询方法的选择取决于操作系统。在 linux 上,使用 epoll,最好是边缘触发。在 FreeBSD 上,使用 kqueue。在 Windows 上,使用例如WSAEventSelect 和 WSAWaitForMultipleEvents。

你的主循环应该是:

for (;;) {
  epoll(); // blocking poll until an event happens, optionally with a timeout
  // iterate signaled sockets and process data
  // Other tasks
}

您是选择在线程池中的每个线程中实现它,还是在主线程中只实现一次,取决于您应用程序的其余部分。关键是让轮询函数做等待,这样就不会占用过多的CPU。

您可以使用非阻塞套接字或ioctl(FIONREAD... 检查每个套接字上可读的数据量。

我首选的套接字处理 OOP 设计是让套接字完全不知道套接字轮询器。一个套接字轮询器,隐藏用于轮询的实际函数,将接受套接字和它应该监视的事件,例如它是否正在轮询?一个tick() 函数,然后告诉每个套接字一个外部监听类,该类与套接字有关。比如:

class SocketPoller {
public:
  void registerSocket(Socket * s, int EventMask);
  void unregisterSocket(Socket * s);
  virtual void tick() = 0;
}

class SocketPollerEPoll : public SocketPoller {
public:
  void tick() {
    epoll(...); 
    // for each socket with events:
      TheSocket->notifyReadable();
  }
};

class SocketPollerSelect : public SocketPoller {
public:
  void tick() {
    select(...); 
    // for each socket with events:
      TheSocket->notifyReadable();
  }
};

【讨论】:

  • 好的,所以当我轮询套接字时,我可以根据我的连接端口轮询一个大组,还是需要根据每个连接的特定端口轮询每个单独的连接? (很抱歉,我之前从来没有做过异步套接字编程,我可能会直接潜入,一旦我明白了大致的想法)
  • 首先基于select() 实现一些东西——这很容易开始。这个想法是将一组 set 套接字传递给轮询函数。然后,轮询函数将告诉您发生事件的套接字子集。您可以设置 50 个套接字并选择它们的可读性,并且 select 可能会返回通知您“这 6 个是可读的”。
  • 哦!这就说得通了!谢谢!我现在开始使用 select(),我会告诉你它是怎么回事。
【解决方案2】:

即使这个问题已经得到解答,您也可以考虑使用Boost.Asio 作为您的通信框架。它很好地将各种平台上的各种轮询方法包装到一个干净、一致且类型安全的仅标头库中。它很成熟,得到很好的支持,并且经常discussed on SO

【讨论】:

  • 我在很多地方都看到过它的讨论,你知道速度比较是什么(低级套接字和boost lib之间)吗?
【解决方案3】:

您可以使用 Push 框架,http://www.pushframework.com 它有效地使用异步 IO。还将抽象低级细节,以便您可以专注于应用程序的业务逻辑。

【讨论】:

    猜你喜欢
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 2011-06-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-23
    相关资源
    最近更新 更多