【问题标题】:Cross-Platform Networking Code in C++?C++ 中的跨平台网络代码?
【发布时间】:2011-12-05 17:27:35
【问题描述】:

我开始开发一个新的应用程序,虽然我的背景主要是基于 Mac/iOS 的,但我需要开发一个 Windows 应用程序才能参加他们的 Imagine Cup。

这个项目包括客户端之间通过套接字连接(到服务器,而不是临时)的通信,我需要 Mac 和 Windows 客户端能够相互通信。我还希望不必编写此网络代码两次,而只需在两个平台上编写不同的本机 UI 代码。这使得网络更容易(我相信两个不同的平台不会以不同的方式与服务器交互)并允许在两个平台上使用本机 UI。

C++ 是完成这项任务的最佳语言吗?两个平台上的标准库是否相同?我知道我必须使用 Microsoft 的 Visual C++ 库,因为似乎很难从 C# 中使用 C++ 代码;这是真的吗?

我以前从未真正编写过跨平台应用程序,尤其是处理平台之间网络的应用程序。

【问题讨论】:

标签: c++ windows macos networking cross-platform


【解决方案1】:

如果您打算使用 C++,我强烈建议您查看 Boost 中的 ASIO,这是第二个上面的“the_mandrill” - 这是一次编写代码并支持两个平台的好方法。

关于 C++ 是否是正确的语言是相当主观的。我个人的感觉是,如果您需要询问,很有可能,这不是最好的方法。

选择C++实现网络代码的原因有:

  • 可以通过精心设计和实现的代码实现极低的延迟和高吞吐量。
  • 可以显式控制内存管理 - 避免与垃圾收集相关的性能变化。
  • 有可能将进程内网络代码与其他本机库紧密集成。
  • 有可能构建适合在资源受限环境中部署的小型组件。
  • 对 C 套接字 API 的低级别访问公开了诸如套接字选项等功能,以使用普通 TCP/IP 和 UDP 之外的协议。

避免使用 C++ 的原因是:

  • 与高级语言(例如 Java/C#/Python 等)相比,开发代码的效率较低
  • 重大实施错误(指针滥用等)的可能性更大
  • 需要额外的工作来验证代码在每个平台上的编译。

您可以考虑的替代方案包括:

  • Python... 直接使用低级套接字支持或高级 Twisted 库。使用方便的高级习语和最少的移植工作进行快速开发。最大的缺点 - 对利用多个处理器内核进行高吞吐量系统的支持不佳。
  • Ruby(socket)/Perl(IO::Socket)... 高级语言,如果将通信信息表示为文本字符串,则可能特别适合。
  • Java...垃圾收集简化了内存管理;范围广泛的现有库。
  • CLR 语言(C# 等)也会进行垃圾收集 - 就像 Java...WCF 是一个有效的框架,可以在其中开发定制协议...这可能很有用。

您还问:“我知道我必须使用 Microsoft 的 Visual C++ 库,因为从 C# 中使用 C++ 代码似乎很难;这是真的吗?

您可以完全避免使用 Visual C++ 库 - 要么使用 C++ 以外的语言进行开发,要么使用替代的 C++ 编译器 - 例如 Cygwin 或 MinGW 提供 G++...尽管我建议使用 Visual C++ 来构建 C 和适用于 Windows 的 C++ 代码。

从 C# 中使用 C++ 代码并不难——尽管我不推荐它作为一种方法。它可能过于复杂。 Visual C++ 可以(可选地)从 C++ 源代码编译“托管代码”(有一些语法扩展需要掌握,使用 Mono 而不是 Visual C++ 的互操作语法略有不同,但恕我直言,这些不是主要问题。)这些 CLR 对象直接与 C# 对象交互,并且可以毫无问题地链接到一个程序集中。使用 Pinvoke 访问本机 DLL(可能使用 C++ 为本机架构编写)也很容易。然而,所有这些都有些无关紧要,因为 .Net 框架对 system.net 中的低级网络(类似于 Winsock[2] 提供的网络)有很好的支持——这为类似设施提供了一个方便的面向 C# 的接口,并且将如果使用 C#(或 VB.Net 或任何其他 CLR 语言),可能会提供更方便的 API 进行开发。

【讨论】:

  • 我认为你列出的 C++ 的前两个缺点只有在开发人员不精通 C++ 时才相关(或者换句话说,它假设他们不精通)。
  • 生产力和错误的可能性是主观的,我承认....并且对语言的熟悉仍然相关。然而,我认为,任何足以实现良好 C++ 的开发人员都可以很快熟练地使用其他语言的高级习语进行开发——并从中获益。这绝不是哪种语言“最好”的问题,而是哪种工具最适合每个给定项目的特定要求的问题。
  • 我正在研究 C++,因为从我的 Objective-C 和其他 C++ 代码(或者......可能是 C#)访问代码相对容易窗边。 --我已经做了一些python,但是让python代码(这将是我的应用程序的网络部分)与Objective-C和C++接口似乎有点复杂和复杂,这意味着在这两个平台上都很痛苦.有什么更简单的(对于 python、ruby 或 perl 等)存在吗?
  • 总的来说,我强烈反对每个进程使用一种以上的技术——也许每个项目使用一种以上的技术——尽管一个定义良好的协议应该最大限度地减少使用一种技术的开销客户端和另一个用于服务器。如果其他考虑因素将您限制在 Objective C(虽然我不太熟悉该语言),我建议查看它的库... AsyncSocket、CFSocket 和 CFStream 类值得注意。如今,(互)网络支持几乎无处不在——选择一种语言,然后查看其可用的库。 :)
  • 好的。我认为你也是对的。我计划非常非常好地记录协议(因为这是一个我计划在未来很远的应用程序)并且我尝试编写一些 Objective-C++ 代码,并且......它被证明是非常奇怪和古怪。另外,我做的 C# 比 C++ 多,而且据我所知,Windows 应用程序用 C# 编写要容易得多。 -- 看起来我会非常好地记录网络代码,并在每个平台上复制它。应该不会太难。感谢您的大量帮助!
【解决方案2】:

我建议你看看Qt。 IMO Qt 是用于跨平台应用程序的最佳 C++ 库之一。 Qt 与 Boost 相比的优势在于 Qt 甚至有 GUI 类。

【讨论】:

  • 另外,Qt 有QStateMachine,可用于实现快速可靠的消息解析逻辑。
  • 很遗憾,我必须利用微软的技术来参加微软的比赛。此外,我对 Objective-C 和 Cocoa 有广泛的了解,所以我想尽可能地使用它。
  • 对于 MS 技术,我认为您需要针对 CLR。这个问题的答案可能会对您有所帮助...stackoverflow.com/questions/245721/…
【解决方案3】:

最佳语言是非常主观的,但如果您想要具有有用抽象和 C 风格语法的可移植快速代码,C++ 是一个不错的选择。请注意,如果您还没有任何 C++ 知识,那么学习曲线会很陡峭。

根据 ISO 标准定义的库在每个平台上的定义都是相同的,但它的实现可能会或多或少符合要求。也就是说,gcc、clang 和 MSVC(post .net) 都很好地实现了 C++98。只要你不使用编译器特定的扩展。

我强烈建议为您的网络查看 boost asio(以及一般的 boost 库),它使用非常有效的前摄器设计模式。但是,您确实需要一些时间来了解它。

http://www.boost.org/doc/libs/1_48_0/doc/html/boost_asio.html

坚持使用标准库和 boost,在大多数情况下跨平台问题不是主要问题。

最后,我会避免使用 C++11 的特性来编写跨平台代码,因为 MSVC、GCC 和 Clang 都实现了标准的不同部分。

【讨论】:

  • 非常整洁,谢谢!为了在两个平台上编译 C++,我需要做些什么吗?预处理之类的? - 另外,任何人都可以推荐一些资源来开始使用 C++(我以前使用过但没有广泛使用)并将其与 Objective-C 代码接口? -- 你们总是让我惊讶,你们总是乐于助人,谢谢!
  • 避免使用 C++11 功能 --> 使用您想要使用/支持的编译器。 Clang 肯定会迎头赶上,如果您真的需要 MSVC 兼容性,请坚持使用它的功能集。
  • Vanilla C++ 可以在任何 C++ 编译器上编译...但是要完成很多有用的工作,您需要使用 API,并且在使用 API 时了解哪个平台(S)很重要API 可以工作。例如,如果您使用 Win32 API,您的代码将只能在 Windows 下编译。 BSD 套接字 API(socket()、bind()、select() 等)将(大部分)在几乎任何操作系统下工作,因此您可以将它用于跨平台网络。但是,如果您是 C++ 新手并且想要更轻松的学习曲线,我强烈推荐 Qt。即使您不需要 GUI,信号和插槽也比裸 BSD 套接字更易于使用。
【解决方案4】:

如果您想花一年时间投入 1000 小时,请务必使用 boost::asio。或者,您可以使用围绕 boost::asio 构建的库,该库调用 C++ 网络模板。这是跨平台网络,您可以在这里找到它: https://bitbucket.org/ptroen/crossplatformnetwork/src/master/

它可以在 Windows、Android、Macos 和 Linux 上编译。

这并不是说如果您在 boost::asio 方面的绝对专家水平可以在性能上做得更好一点,但是如果您想获得 98% 的性能提升,您可能会发现它很有用。它还支持HTTP、HTTPS、NACK、RTP、TCP、UDP、MulticastServer和Multicast Client。

示例: TCP服务器:https://bitbucket.org/ptroen/crossplatformnetwork/src/master/OSI/Application/Stub/TCPServer/main.cc HTTP服务器:https://bitbucket.org/ptroen/crossplatformnetwork/src/master/OSI/Application/Stub/HTTPServer/httpserver.cc

OSI::Transport::TCP::TCP_ClientTransport<SampleProtocol::IncomingPayload<OSI::Transport::Interface::IClientTransportInitializationParameters>, SampleProtocol::OutgoingPayload<OSI::Transport::Interface::IClientTransportInitializationParameters>, 
    SampleProtocol::SampleProtocolClientSession<OSI::Transport::Interface::IClientTransportInitializationParameters>, OSI::Transport::Interface::IClientTransportInitializationParameters> tcpTransport(init_parameters);;
SampleProtocol::IncomingPayload< OSI::Transport::Interface::IClientTransportInitializationParameters> request(init_parameters);
request.msg = init_parameters.initialPayload;
std::string ipMsg=init_parameters.ipAddress;
LOGIT1(ipMsg)
tcpTransport.RunClient(init_parameters.ipAddress, request);

我有偏见,因为我编写了库。

【讨论】:

  • 添加代码而不是链接是个好主意,因为代码以后可能会更改。此外,如果您真的想添加一些链接,您可以在上下文部分添加这些链接。
  • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
【解决方案5】:

您还可以检查此通信库: finalmq

此库具有以下属性: C++、跨平台、异步/非阻塞、多种协议(TCP、HTTP、mqtt5)、多种编码格式(json、protobuf)。检查示例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 2014-04-12
    • 1970-01-01
    • 2011-01-13
    • 2010-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多