【问题标题】:C++ and network socketsC++ 和网络套接字
【发布时间】:2017-05-11 07:55:57
【问题描述】:

我曾涉足 C,目前正在学习 C++。

我想学习标准库(std:: 命名空间),所以我正在做一些项目。一个是一个简单的电子邮件程序,它登录到我的本地 SMTP 服务器并显示我的电子邮件,并具有发送邮件的能力。我为这种旧感觉添加了一点 ncurses。

问题是,我还没有找到使用网络套接字的标准库方法。似乎我必须在 C sys/socket.h 中使用网络套接字,但最后我得到了一个文件描述符,它留下了 read()write()send() 函数调用。我希望能够使用std::fstreamstd::ostream 类。但是open() 成员函数采用文件名,而不是文件描述符。

我知道 Boost 库有这个功能,但是模板之类的东西让我头疼,我现在只想坚持使用标准库。

在继续之前,我只想确保没有更好的方法将read()write() 转换为connect() 网络套接字C 函数返回的文件描述符。

【问题讨论】:

  • 您能否发布一些示例代码,展示您如何尝试使其工作,以及哪些工作有效但不是std::
  • 为此在 C++ 中使用 C 套接字 API 没有任何问题(我一直都这样做)。你认为其他人的套接字库是如何实现的?一切最终都必须通过操作系统提供的套接字 API,而在 C/C++ 中,BSD 样式的套接字函数(connect()send()recv() 等)可以在大多数平台上移植。 Boost.ASIO、ACE、CURL 等都是基于此构建的。而SMTP 使用 C 套接字函数实现起来并不难。
  • 您的问题是关于 C++,而不是 C。请不要标记垃圾邮件...
  • 自 2019 年起,您可以使用 kissnet 库,它包装了 socket.h(以及 Windows 上的 winsock.h),并通过 OpenSSL 提供了安全套接字。

标签: c++ sockets standards


【解决方案1】:

标准库不包含套接字或任何网络支持。

你的选择是

  1. BSD 套接字,如果您在 *nix 上通过操作系统特定的库
  2. BSD 阻塞套接字,如果您在 Windows 上,则通过 Winsock
  3. 异步套接字,如果您在 Windows 上,则通过 Winsock 和 Windows 消息泵
  4. IOCP,如果您在 Windows 上,通过 Winsock
  5. Boost ASIO,它是便携式的。
  6. 其他第 3 方库,其他人使用上述方法之一并为您打包。

在所有这些中,我个人认为 Boost ASIO 是最容易使用的。我建议至少阅读有关阻塞 BSD 套接字的教程,以了解概念。

所有这些,除了 5 和 6,都将非常像 C。网络编程确实不是面向对象编程和 C++ 统治旧 C 风格的利基市场。你可以包装东西,但这是你所希望的最好的。

您真的不会在套接字代码中使用 fstream 或 ostream。也许在它上面的一层,但最终,所有这些实现都是相似的,因为您将发送和接收二进制数据或文本的字节。

【讨论】:

  • 很抱歉,这根本不正确。自 c++ 11 起,C++ 就提供了适当的生产质量网络库,在 C++ 17 中,它正式成为标准库的一部分。
  • 给我的消息。命名它/链接它。我的谷歌搜索一无所获。我幻想自己在 C++11 上的速度非常快。 C++17 没那么多。
  • C++11 包含标准网络库。 C++ 编译器供应商可能包含他们自己的库,但至少在 C++17 之前,网络不会成为标准库的一部分(请参阅N4656: Working Draft, C++ Extensions for Networking)。
  • @Patrick 再次命名/链接它。几十年来一直在谈论。有提案。 C++03、11 或 14 标准中没有包含任何网络支持。如果您可以向我展示执行网络的代码,同时在所有正式支持 C++14 的编译器上只链接到 CRT,我今天将向您提供 6 件套。
  • Experimental 不是标准,不保证永远是标准的。根据其定义,它是“实验性的”。我不做,也不应该跟上每一个进入实验阶段的提案。我编写真实的生产代码并为其他也编写真实生产代码的专业人员回答问题。
【解决方案2】:

您可以将std:::istreamstd::ostream 与套接字一起使用,您只需编写自己的(或找到预先存在的第3 方)自定义std::basic_streambuf 派生类,该类使用套接字I/O 而不是文件I /O,然后您可以通过其构造函数或rdbuf() 方法将该类的实例分配给std::(i|o)stream

【讨论】:

  • 试过写一个吗?这是可能的,但非常困难,并且没有任何流文档会真正告诉您如何做到这一点。
  • 这对于那些说“模板之类的东西超出我的想象”的人来说真的很实用吗?他正在寻找一个预先存在的库,这使它在这里偏离主题。
  • 您无需了解模板编程即可派生streambuf 类。派生类是 C++ 编程的难点,因此它是一项很好的学习技能。此外,我确实说过“或者找一个第 3 方班级”。有可用的socketstreambuf类,如this one
  • 只是想知道。我的兄弟,他不是笨蛋,大约 25 年前就这样做了,他说这是他职业生涯中最糟糕的经历之一。 std::stream 类显然没有被设计或记录为子类或扩展,而只是形成一个整体块。这一切都归结为在某处实现单个reset() 方法,该方法根据天气进行输入和输出!但我暂时不能同意“派生类是 C++ 编程的难点”,除非是像这样设计不佳的类层次结构。
  • 它也不是很买你。您肯定不想在套接字上使用被滥用的 > 运算符来格式化数据,而您真正获得的唯一另一件事是基本的 EOS 和错误处理。
猜你喜欢
  • 1970-01-01
  • 2013-02-19
  • 1970-01-01
  • 1970-01-01
  • 2013-03-18
  • 1970-01-01
  • 2013-08-28
  • 1970-01-01
  • 2021-12-03
相关资源
最近更新 更多