编写推送到客户端的服务器应用程序(TCP)
Writing a server application that Pushes to clients (TCP)
我正在编写一个客户机-服务器应用程序,其中一个需求是服务器在接收到来自其中一个客户机的更新后,能够将新数据推送到所有其他客户机。这是一个c++ (Qt)应用程序意味着在Linux上运行(客户端和服务器),但我更寻找高层次的概念的想法,这应该是如何工作的(虽然低级的想法也很好)。
服务器:
它需要(在它的其他职责中)保持一个套接字打开,监听来自潜在的n不同客户端的传入数据包,可能是在后台线程上(我没有写太多关于套接字的代码,除了在学校的一些下流的例子)。在从客户端获得这些数据后,它对其进行处理,然后将其分发给所有客户端,对吗?
当然,我不确定它是如何做到这一点的。我猜这意味着它必须与每个客户端(至少是活动客户端)保持持久连接,但我甚至不理解如何在概念上维护这个连接(或这些连接的列表)。
那么,我应该如何处理这个呢?
通常,当您有多个客户端时,有几种方法可以处理此问题。
首先,在TCP中,当客户端连接到您时,它们被放置到队列中,直到它们可以被服务。这是给定的,除了调用accept
系统调用来接收新客户机之外,您不需要做任何事情。一旦接收到客户端,您将获得一个用于读写的套接字。谁先读/先写完全取决于你的协议,但双方都需要知道协议(这由你来定义)。
获得套接字后,可以做一些事情。在一个简单的情况下,您只需读取一些数据,处理它,回写到套接字,关闭套接字,并为下一个客户端提供服务。不幸的是,这意味着您一次只能服务一个客户端,因此不可能"推送"更新。另一种策略是保留所有打开的套接字的列表。任何"更新"都只是遍历列表并写入每个套接字。这可能会出现一个问题,因为它只允许推送更新(如果客户端发送请求,谁会监视它呢?)
更高级的方法是为每个套接字分配一个线程。在此场景中,每次创建套接字时,都要启动一个新线程,其全部目的是为一个客户机提供服务。这样可以减少延迟并利用多个内核(如果可用),但编程难度要大得多。如果你有1万个客户端连接,那就有1万个线程,这就太多了。将更新推送到单个客户端(在此场景中)非常简单(线程只向其相应的套接字写入)。一次性推送到所有这些线程有点棘手(需要线程事件或生产者/消费者队列,这两个都不是很有趣的实现)
当然,还有许多其他方法可以处理这个问题(每个客户端一个进程,一个线程池,一个负载平衡代理,你能想到的)。我只想说,没有办法在一个答案中涵盖所有这些。我希望这回答了你的基本问题,让我知道如果你需要我澄清什么。这是一个非常大的课题。然而,如果我可以提出一个建议,处理多个客户是一个已经被重新发明了一百万次的轮子。市面上有很多非常好的库,它们比原始套接字IO更高效,对程序员也更友好。我推荐libevent,它将网络请求转换为事件驱动的范例(更像GUI编程,这可能对您很好),并且非常高效。根据我的理解,我认为您需要保持一个无限循环,(至少直到程序终止),以回答来自客户端的连接请求。最好将它们添加到某种类型的数组中。使用事件查看何时将新客户端添加到该数组中,并等待其中一个客户端提供数据。然后你对这些数据做你该做的,然后吐出来。
- 使用嵌入式猫鼬服务器托管应用程序
- 在 1 个服务器 n 客户端套接字 C++ MFC 应用程序中更新数据的客户端
- 在 Ubuntu 服务器上运行 QT 应用程序时崩溃
- 使用C++创建UDP服务器以嵌入跨平台iOS和Android应用程序中
- 我正在编写一个简单的客户端套接字应用程序,但在连接后服务器收到一个空缓冲区
- C++客户端/服务器聊天应用程序 - 从 Ubuntu 命令窗口扫描输入
- C :如何使用log4cplus的套接字应用程序将日志发送到Logstash服务器
- C++应用程序连接到网站服务器并根据密码检索文件
- 使用 QT 开发服务器应用程序是个好主意吗?(QT5)
- 开发C++应用程序,目标服务器有不同的std lib版本,最佳实践是什么
- 在 Ubuntu 上运行的节点服务器需要执行 C# 应用程序 - 如何执行
- 使用WordPress在网络服务器上运行C 应用程序
- 在POCO服务器应用程序中预防目录遍历攻击
- 如何将C++应用程序与节点.js服务器连接以获取 JSON 数据
- UWP 应用程序拒绝接收 P2P 服务器部件中的数据
- 我们如何远程调试在 Linux 服务器上运行的C++应用程序
- 为什么在应用程序服务器项目中使用多种语言
- 如何设置C++web应用程序服务器侦听来自tomcat/restlet服务器的http请求
- 当远程桌面会话注销时,如何阻止DLL终止应用程序服务器
- -客户端-服务器应用程序-服务器端的recv()可以正常工作,但客户端的recv()会阻塞程序