2012-02-24 39 views
2

第一件事是,我是一个很长时间的潜伏者,但第一次用户,我想感谢您创建网站!专用协议的长期多线程客户端(Python,select,epoll)

我处于需要实现专有协议的客户端部分的情况。该协议使用TCP/IP的下方和消息流可以被总结如下:

  1. 客户机连接到服务器
  2. 客户端表示在一个特定类型的数据中的感兴趣
  3. 如果服务器具有任何这样的数据,它它发送到客户端
  4. 客户确认接收到服务器
  5. 客户现在需要告诉它仍有意在同类型
  6. 服务器的数据的服务器将数据发送到客户端它是在
  7. 客户未来需要的应用程序级的保活请求从时间发送到服务器的时间(如每分钟左右)
  8. 从服务器的一些消息需要客户端发送回复回服务器
  9. 客户端断开

所有这一切是在一个TCP会话,这将是一个长期的活的,有点像我的WebSocket想象中发生。

另一件事是,所述客户端将被部署在多线程服务器上,并且应该允许从多个线程的并发访问,这意味着单个线程应该能够从到“订阅”到某一类型的消息服务器也应该能够发送消息给它。

我非常了解GIL,因此我猜这并没有太多的评论,我只写了一个客户端,我无法改变任何其他的架构。

因此,事情是我从来没有深入HTTP层次,我很幸运,总是使用一些已经存在的库,另一方面,我没有做过那么多的网络编程,那将是我第一次成为这样的人。

我希望它能成为我学习更多关于select,epoll,libev或gevent等异步库/工具/工具包的机会。

麻烦的是,网络上的大部分资源都与编写服务器有关,我甚至不确定是否要在多线程上部署客户端并不意味着它们都不会多做。所有服务器的人显然都是单线程的,但不清楚是不是因为多线程不需要,或者是因为像epoll这样的东西并不真的喜欢使用它们的多线程。

服务器清楚地对待所有客户端,就像它们是单线程单元一样,所以我想我需要序列化访问客户端。我无法得到的是如何确保服务器响应匹配线程,反之亦然。如果一个线程收到一条消息,但另一个线程需要确认它在收到消息之前收到的消息,那么我怎样才能确保消息不会混淆?

你怎么看待这一切?在这种情况下,异步库是不错的选择吗?你能想到我可以看看的任何代码示例吗?我使用的是Python,但我认为这个问题足够通用,我可以使用C,C++或Java来获得灵感。

很多,非常感谢!

回答

0

每个线程(每个客户端)是否可以打开自己的套接字?在这种情况下,这完全是一个非问题:只有该线程中的客户端在该套接字上具有句柄,因此它会自动从服务器获取正确的数据。对于服务器,来自客户端的所有这些连接将看起来像完全独立的客户端连接(这正是它们的原理)。

如果其中一个要求是限制网络连接的总数,那么您可以构建一个特殊线程来维护到服务器的连接,并且在本地接收来自各个线程的通信请求/但是使用独立套接字每个线程一个)可能要简单得多。

您是否绝对必须使用应用程序级保持活动?因为TCP可以自动为你做到这一点。如果没有及时收到keepalive,那么套接字会关闭,从而通知对方连接已超时。如果在你的情况下可能,请考虑将它作为一个选项。最后,如果您不必执行应用程序级别的keepalive,那么您可以利用多线程编程的一个好方面:将每个线程开发为好像它是唯一的一个线程,然后您不用根本不需要担心任何异步。例如,您可以编写客户端发送请求,然后阻塞 - 等待响应,计算并发送结果或检查服务器是否有更多数据到达。来自服务器的数据将累积在您的TCP接收窗口中。这也可以作为流量控制的一种手段:如果客户端变得太慢并且接收窗口已满,则服务器无法再发送。这可能会阻塞服务器,所以您需要查看服务器是否可以处理这种情况。