【问题标题】:How to build a robust network architecture using sockets [closed]如何使用套接字构建健壮的网络架构 [关闭]
【发布时间】:2016-04-28 13:29:44
【问题描述】:

我必须从一台服务器连接到多台 PC(约 1000 台 PC)。这些电脑通过同一建筑物内的 Wifi 网络连接。

每台 PC 都有与服务器的专用连接。通过它的 IP 地址,服务器知道要为他生成的具体数据。

我必须通过网络向每台 PC 发送专用的短字符串。 (一个字符串约 30 个字符)

专用字符串以每秒 30 个字符串的频率发送到每台 PC。

问题是这些发送的数据很关键,应该实时发送。

就我而言,哪种解决方案更快、最可靠?

【问题讨论】:

  • 每秒 900 字节几乎不是“高频”。
  • 但是问题就完全不同了!!!您需要一些广播,而不是两台 PC 之间的消息传递。而且您仍然没有在新问题中说明 PC 的物理位置?同一个房间还是不同的大陆?
  • 现在我们有一个值得回答的问题!我自己来回答!
  • 当您说“专用”时,您的意思是每台 PC 都会收到一个唯一的字符串吗?还是所有 PC 共享发送的字符串?
  • @ProEns08:养成改善问题的习惯,而不是在被要求时发表评论。基本上,cmets 是为其他人服务的;您有权通过编辑来改进您的问题,那就这样做吧!

标签: c++ sockets http networking server


【解决方案1】:

我假设您有两台 PC 通过以太网或 wifi 连接,或者足够好的现代互联网连接(都在地球上;没有星际...;没有 1970 年代的鸽子 IP RFC1149 或 1200 波特模拟调制解调器)。 那么每秒大约 30 个字符的 30 个字符串大约是 每秒一千字节,不是大不了,当然不是 高频 如您所说。 我目前在家(法国巴黎附近)的光纤互联网连接能够每秒下载十几兆字节,并且每秒至少上传一兆字节。几年前,它是 ADSL,每秒下载大约 1 兆字节。我在家里从来没有互联网连接,每秒 1 千字节是高负载。 (如果你在星际空间,或者在非洲或南极洲最偏远和荒凉的地方,那么 1Kbyte/sec 可能在 2016 年是一个问题,但是你在互联网连接方面很不走运。

您的 HTTP 设置可能使用 websockets(有点像您的第二个解决方案)。您可以在服务器端使用libonion(HTTP 服务器库),在客户端使用libcurl(HTTP 客户端库)。定期轮询(例如每秒发出二十次 HTTP 请求)将需要更多资源(但这仍然是可管理的)。 HTTP 连接会更慢,因为 HTTP 会增加一些开销(HTTP 请求和响应中的标头)。

请注意HTTP 协议高于 TCP/IP,因此肯定会在提供它们的操作系统(Linux、Windows、MacOSX...)上使用BSD sockets。所以“网络解决方案”已经在使用套接字了。

如果您使用套接字,则需要在它们上定义一个协议(或使用一些现有的协议,如 HTTP 或 JSONRPC)。

我将采用套接字方法。可能是一些与 JSON 相关的东西,比如 JSONRPC。请注意,如果您在套接字 API 上编码,则 TCP/IP 是一个没有消息边界的流协议。您需要在两侧进行缓冲,并定义一些消息边界约定。您可以发送JSON,以换行符结尾(结尾换行符与 JSON 兼容,便于分隔消息)。

您可能对 0mq 等消息传递库感兴趣。

附录(问题版后)

您的新问题大相径庭(数以千计的 PC,而不仅仅是其中的两台;我猜它们在同一栋建筑中,或者至少在同一个大陆。)。您需要大约 1000 * 30 * 30 即小于每秒 1 兆字节的带宽。 我仍然建议使用一些套接字。可能0mq 更相关。您可以将每条消息设为 JSON。您需要很好地记录您正在使用的协议。可能,您希望服务器有 几个 线程(例如,十几个,而不是数千个线程)来循环发送消息(在 TCP 上)。或许您可能希望拥有一个具有多个以太网连接的服务器(但每秒兆字节可以在一个以太网上运行,甚至是一个 100Mbits/sec 的)。

【讨论】:

  • 你最近的编辑让我有点疑惑。 JSON 本身就是一条消息,那么为什么不需要人为的消息边界呢?
  • 因为痛苦的经历,在没有明确的消息边界结束的情况下手工编写 JSON 内容有点痛苦。在末尾添加换行符与 JSON 兼容,并大大简化了操作。
  • 不知道到底有多痛苦,JSON解析需要流,在TCP socket之上实现流接口很简单。
  • @BasileStarynkevitch:对不起,如果在不到一小时的时间内社区仍然不欢迎这个问题(3 次反对票),我应该删除这个问题。我应该尊重社区。这是 SergeA 不赞成宣传的结果之一。
  • 不仅如此。你的问题问得很糟糕,在我要求改进版本后你没有改进它。所以我也投了反对票(如果您通过提供更多上下文正确编辑您的问题,我将恢复我的反对票)。
【解决方案2】:

30 字节,每秒 30 次,就是每秒 900 字节。这根本不快。任何一种方法都可以正常工作。请注意,HTTP 连接无论如何都使用套接字。

听起来您的“套接字”选项意味着保持套接字连接始终打开所有,而不是 HTTP,其中(通常)为每个请求打开一个单独的连接。我想你真正要问的是:

  • 让客户端定期询问服务器是否有新数据,或者
  • 让服务器在新数据可用时立即发送。

这完全取决于您的程序要求是什么,我们不知道。

【讨论】:

  • HTTP 没有为每个请求打开一个套接字。
  • @BasileStarynkevitch,HTTP/1.0 可以:)
  • 不过今天有点过时了....
  • @Wyzard:对不起,如果在不到一小时的时间内社区仍然不欢迎该问题(3 次反对票),我应该删除该问题。我应该尊重社区。这是 SergeA 不赞成宣传的结果之一。
  • @Wyzard:是的,谢谢,+1。
【解决方案3】:

一千个双向 TCP 通信需要 1000 个套接字(除非您想为每个发送的字符串打开和关闭连接,但这会极大地消耗性能)。

这危险地接近于最大打开文件描述符的惯常软限制(即 1024)。它是习惯硬限制 4096 的 25%。鉴于此,我发现 TCP 不太适合这里。

相反,我建议使用 UDP。使用 UDP,您只需要几个套接字(即使一个也可以,但如果使用多个,您可以更好地扩展)。它会有可靠性问题,但您可以在 UDP 之上实现某种形式。

【讨论】:

  • 在我的桌面 Debian/Linux PC 上,默认文件描述符限制是 65536,而不是 1024。我不确定 UDP over Wifi 是否足够可靠。
  • @BasileStarynkevitch,我猜,习惯因您的习惯而异。我发现我提供的限制通常存在于我使用过的服务器上,当然还有 YMMV。
  • 你真的遇到过 2016 年限制为 1024 fd 的服务器吗?哪个操作系统和版本?
  • @BasileStarynkevitch 现在:~>ulimit -Hn: 4096ulimit -Sn: 1024cat /etc/system-release: Red Hat Enterprise Linux Server release 6.4 (Santiago)
  • 你应该升级到 Debian :-)
【解决方案4】:

请熟悉OSI model。 套接字(UDP、TCP)在第 4 层,HTTP 在第 5 层,因此已经使用第 4 层协议。

【讨论】:

  • OSI 模型仅作为学术模型。在现实生活中,界限是模糊的。
  • 对于新手来说,了解结构是一个很好的起点。
  • @ProEns08,你的问题仍然很糟糕,糟糕的问题值得反对。对不起,生活的事实。下次要更加小心,在提问之前先进行研究,您的问题将被投票。
  • 没问题....
  • @ProEns08,有 5 人反对。你真的给了我太多的信任。我没那么有魅力。
猜你喜欢
  • 2010-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多