由于有多种连接多客户端到服务器的方式,例如:fork,select,threads等。如果能描述哪个更好地将多个客户端连接到服务器,我会很高兴。将多个客户端连接到服务器的好方法是什么?
回答
设计一些心跳循环,它会遍历所有的套接字并响应它们各自的事件。
我推荐服务器是被动的(客户端将连接到它,而不是服务器连接到客户端),因为它通常在网络上完成。因此,它也会有一个监听套接字。
心跳循环是一个坏主意。因为它意味着支票之间的强迫睡眠(也许你有其他的想法,在这种情况下忽略这一点)。已经有一个API等待一组套接字上的数据。看看'http://linux.die.net/man/2/select' – 2009-12-24 18:17:00
和Linux上的epoll,BSDs/MacOSX上的kqueue等等:) :) – 2009-12-24 19:47:26
@martin,你等一组套接字,但是你查看所有列表并查看获得的事件。 – 2009-12-24 19:58:13
我知道在C中fd_select提供了这种轮询套接字的能力。不确定,但我猜测C#有更好的方法来做到这一点。
谢谢!你能解释一下你的意思是什么?“轮询插座的能力.. – make 2009-12-24 15:26:51
一个简单的建议,避免使用fork,因为它会创建一个重量级的进程,使用线程而不是轻得多,并共享当时创建的进程的相同内存空间。
这取决于操作系统。在UNIX上,fork()和进程是有效的。线程之间共享的地址空间也会导致很难产生错误。总之,流程和线程都有优点和缺点。 – 2009-12-24 14:13:17
谢谢!我知道fork()在Windows上不受支持 – make 2009-12-24 21:53:02
至少有两个选项。
- 创建一个监听套接字。
- 等待连接。
- 产生一个线程来处理连接。
或
- 创建一个监听套接字,并等待它使用select()。
- 如果侦听套接字fd变为活动状态,则建立新的连接并将新的fd添加到选择呼叫。
- 如果连接fd变为活动状态,则处理它。
如果你了解线程,第一个选择可能是一个更清洁的方法。第二种方法需要一些fd管理(例如监听或连接),但可以在单个线程中完成。
what do you mean by this <<the first alternative might be a cleaner approach>>? can you explain pls?
如果你理解了线程和线程之间的同步,第一种方法可以更简单,因为你可以使用正常封闭读取和写入连接插座。
第二种方法要求您使用非阻塞读/写和处理部分数据包,如果你想能够同时处理所有的客户端。
如果您的程序在Windows上运行。完全避免线程和进程,并使用套接字编程的异步模型。这是迄今为止进行网络通信最有效(最简单的方法)。
谢谢!你能否解释一下如何在Windows上使用异步套接字以及为什么线程无用...... – make 2009-12-24 21:55:43
如果您使用的是Windows,那么处理大量客户端的最有效方法是围绕异步I/O和I/O完成端口构建服务器。这些允许您以有效的方式为少量(4?)线程服务大量(10万)客户端。
有些人认为I/O完成端口模型的异步性质有点难以理解,但我有一个免费的C++源代码框架,您可以从here下载以帮助您入门。如果您使用的是托管代码,那么.Net框架中的所有异步套接字API都会在“引擎盖下”使用I/O完成端口。
I/O完成端口模型可以很好地扩展,因为它是一个从零开始建立起来的高效操作系统原语;它知道与它关联的线程是否正在运行或等待,因此可以管理它允许同时处理“完成”的线程数量。它也按照fifo顺序使用线程,因此如果没有什么工作要做,那么浪费的上下文切换就会减少,因为只有最小线程数将被使用(而不是跨所有线程调度工作项并导致所有线程堆栈保持分页到内存中)。相比之下,您自己的线程池必须效率较低,因为您不具有与IOCP相同的线程知识水平。选择经常受限于它可以支持的套接字数量,这意味着为了获得真正的可伸缩性,您需要在选择的顶部构建一些复杂的代码,以便能够管理超过此数量的客户端。对每个连接模型使用线程的效率低得多,因为不仅新线程定期启动和停止,而且您在任何时候都不能控制进程中的线程数 - 当您将因素分配给线程时,线程是相对重的资源在他们的堆栈空间等等。一旦你有更多的线程比CPU核心,你将失去在上下文切换(IOCP通常完全避免)的时间。最后,为每个连接分配一个新进程的权重比每个连接模型的线程更重,我个人也没有看到任何理由认为这是现代操作系统的有效选项。
非常感谢回复 – make 2009-12-24 22:33:28
Unix Network Programming的第30章介绍了客户端/服务器设计的替代方案。 UNP书籍是网络编程的最佳开端。
- 1. 将客户端连接到服务器端的方法
- 2. 将多个客户端连接到一台服务器
- 3. 如何将多个客户端连接到服务器
- 4. 将服务器连接到多个客户端
- 5. 为什么我无法将我的FTP客户端连接到服务器?
- 6. 连接到同一台服务器的多个tcpip客户端?
- 7. 什么可能阻止客户端连接到服务器?
- 8. 无法将agsXmpp客户端连接到eJabberd服务器
- 9. 无法将Gloox Xmpp客户端连接到Openfire服务器
- 10. 连接多个客户端到服务器
- 11. 这是在性能客户端更好地连接或服务器端连接
- 12. 客户端连接或服务器端?
- 13. 在服务器上接受客户端的多个连接
- 14. 在Linux服务器上处理多个客户端连接的正确方法是什么
- 15. memcached的客户端 - 服务器模型的好处是什么?
- 16. 维护客户端http客户端 - 服务器连接的正确方法?
- 17. 多套接字客户端连接到服务器
- 18. 我的TCP客户端 - 服务器连接有什么问题?
- 19. 处理多个客户端连接的Perl TCP服务器
- 20. 将非flex客户端连接到运行blazeDS的服务器
- 21. 将客户端连接到工作组中的TFS服务器
- 22. XMPP客户端无法连接到Android中的gtalk服务器
- 23. python TCP客户端无法连接到我的TCP服务器
- 24. 客户端 - 服务器UDP连接
- 25. Oracle客户端服务器连接
- 26. MySQL连接服务器客户端
- 27. 通过单一连接将数千个客户端连接到Jabber服务器
- 28. 服务器端和客户端方法
- 29. 什么是检查WCF客户端连接的最佳方法
- 30. 连接到仿真器服务器的多个仿真器客户端
你能更具体吗? – Andres 2009-12-24 13:45:21
谢谢!再次看到问题,我修改了它... – make 2009-12-24 14:12:50