使用线程是处理UDP服务器同时连接40个客户端的最佳方式吗?

3

我正在开发一个UDP服务器/客户端应用程序。

我希望我的服务器能够同时处理40个客户端。我考虑在服务器端创建40个线程,每个线程处理一个客户端。客户端根据IP地址区分,并且每个唯一的IP地址都有一个线程。

当客户端向服务器发送数据时,主线程提取客户端的IP地址并决定哪个线程将处理该特定客户端。是否有更好的方法来实现此功能?


1
有很多方法可以解决这个问题,使用线程肯定是其中之一。每个客户端有多少流量?每个线程需要完成多少工作?如果只是少量流量和简单的工作,那么仅使用主线程可能就足够了。如果不行,尝试使用一个较小的线程集,每个线程处理多个客户端。 - Some programmer dude
2
我的建议是从一个单一的“主”线程开始执行。如果你发现服务器跟不上,那么就分成两个线程,一个负责通信,一个负责工作。如果仍然不能达到足够好的效果,那么就使用两个线程,每个线程处理一半的客户端。以此类推,直到你对性能感到满意。 - Some programmer dude
1
使用UDP时,您不使用send向客户端发送数据,而是使用sendto。网络堆栈将能够处理它。您只需要小心,不要让多个线程同时调用sendto,可以通过让单个线程执行所有通信或使用互斥锁等方式来保护发送过程。 - Some programmer dude
1
这就是为什么你应该从较少的线程开始,最好根本不要有额外的线程,并从那里逐步增加。 - Some programmer dude
1
你们的目标操作系统是什么?许多操作系统提供不同类型的非阻塞IO功能,可以实现多用户服务器而无需显式地使用多线程。 - Philipp
显示剩余3条评论
3个回答

3

扩展服务器应用程序有不同的方法,如果客户端数量不多,则每个客户端一个线程似乎是不错的选择,但另一种更有效的方法是使用线程池。这些线程作为任务基础工作,每当您有任何新任务时,将此任务分配给空闲的工作线程。


2
WinAPI似乎内置了对线程池的支持。http://msdn.microsoft.com/en-us/library/windows/desktop/ms686760(v=vs.85).aspx - JeremyP

2

看一下这个项目,我认为它对于初学者非常有帮助:http://www.codeproject.com/Articles/16935/A-Chat-Application-Using-Asynchronous-UDP-sockets

使用 IPAddress.Any,我们指定服务器应该接受来自任何接口的客户端请求。要使用特定的接口,我们可以使用 IPAddress.Parse(“192.168.1.1”)而不是 IPAddress.Any。然后,Bind 函数将 serverSocket 绑定到此 IP 地址。epSender 标识数据来自哪个客户端。

使用 BeginReceiveFrom,我们开始接收将由客户端发送的数据。请注意,我们将 epSender 作为 BeginReceiveFrom 的最后一个参数传递,AsyncCallback OnReceive 通过 IAsyncResult 的 AsyncState 属性获取此对象,然后处理客户端请求(登录、注销和向用户发送消息)。请参见附加的代码以了解 OnReceive 的实现。


0
更好的方法是使用Proactor模式(查看Boost.Asio库),而不是为每个客户端创建线程。采用这种方法,您的应用程序将具有更好的可扩展性和性能(特别是在具有本地异步I/O的平台上)。
此外,使用此技术,线程将与并发解耦,这意味着您不一定要处理多线程及其所有复杂性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接