编写推送到客户端的服务器应用程序(TCP)

Writing a server application that Pushes to clients (TCP)

本文关键字:应用程序 服务器 TCP 客户端      更新时间:2023-10-16

我正在编写一个客户机-服务器应用程序,其中一个需求是服务器在接收到来自其中一个客户机的更新后,能够将新数据推送到所有其他客户机。这是一个c++ (Qt)应用程序意味着在Linux上运行(客户端和服务器),但我更寻找高层次的概念的想法,这应该是如何工作的(虽然低级的想法也很好)。

服务器:

它需要(在它的其他职责中)保持一个套接字打开,监听来自潜在的n不同客户端的传入数据包,可能是在后台线程上(我没有写太多关于套接字的代码,除了在学校的一些下流的例子)。在从客户端获得这些数据后,它对其进行处理,然后将其分发给所有客户端,对吗?

当然,我不确定它是如何做到这一点的。我猜这意味着它必须与每个客户端(至少是活动客户端)保持持久连接,但我甚至不理解如何在概念上维护这个连接(或这些连接的列表)。

那么,我应该如何处理这个呢?

通常,当您有多个客户端时,有几种方法可以处理此问题。

首先,在TCP中,当客户端连接到您时,它们被放置到队列中,直到它们可以被服务。这是给定的,除了调用accept系统调用来接收新客户机之外,您不需要做任何事情。一旦接收到客户端,您将获得一个用于读写的套接字。谁先读/先写完全取决于你的协议,但双方都需要知道协议(这由你来定义)。

获得套接字后,可以做一些事情。在一个简单的情况下,您只需读取一些数据,处理它,回写到套接字,关闭套接字,并为下一个客户端提供服务。不幸的是,这意味着您一次只能服务一个客户端,因此不可能"推送"更新。另一种策略是保留所有打开的套接字的列表。任何"更新"都只是遍历列表并写入每个套接字。这可能会出现一个问题,因为它只允许推送更新(如果客户端发送请求,谁会监视它呢?)

更高级的方法是为每个套接字分配一个线程。在此场景中,每次创建套接字时,都要启动一个新线程,其全部目的是为一个客户机提供服务。这样可以减少延迟并利用多个内核(如果可用),但编程难度要大得多。如果你有1万个客户端连接,那就有1万个线程,这就太多了。将更新推送到单个客户端(在此场景中)非常简单(线程只向其相应的套接字写入)。一次性推送到所有这些线程有点棘手(需要线程事件或生产者/消费者队列,这两个都不是很有趣的实现)

当然,还有许多其他方法可以处理这个问题(每个客户端一个进程,一个线程池,一个负载平衡代理,你能想到的)。我只想说,没有办法在一个答案中涵盖所有这些。我希望这回答了你的基本问题,让我知道如果你需要我澄清什么。这是一个非常大的课题。然而,如果我可以提出一个建议,处理多个客户是一个已经被重新发明了一百万次的轮子。市面上有很多非常好的库,它们比原始套接字IO更高效,对程序员也更友好。我推荐libevent,它将网络请求转换为事件驱动的范例(更像GUI编程,这可能对您很好),并且非常高效。

根据我的理解,我认为您需要保持一个无限循环,(至少直到程序终止),以回答来自客户端的连接请求。最好将它们添加到某种类型的数组中。使用事件查看何时将新客户端添加到该数组中,并等待其中一个客户端提供数据。然后你对这些数据做你该做的,然后吐出来。

相关文章: