【问题标题】:'Access Violation', 'bad allocation': POCO NTPClient request C++“访问冲突”、“分配错误”:POCO NTPClient 请求 C++
【发布时间】:2024-01-23 14:46:01
【问题描述】:

我想做一个简单的程序,它执行以下操作: '从互联网时钟获取原子时间'。 我已经编写了另一个使用 FTP 的程序,并且使用 Poco::Net 库。

我尝试使用 NTPClient,因为我读到那是网络时间协议。 更详细地说,这是我使用的信息:

'NIST 服务器在端口 123 上侦听 NTP 请求,并通过以下方式响应 发送 NTP 格式的 udp/ip 数据包。数据包 包括一个 64 位时间戳,其中包含自 UTC 秒以来的时间 1900 年 1 月 1 日,分辨率为 200 ps。'

我的来源是这个网站:nist

此外,我从这里尝试了各种服务器,它们的状态为“所有服务可用”: servers

这是一个崩溃和/或抛出异常的小例子。这是一个异常 std::bad_alloc ,有时它会因“访问冲突”而崩溃(见下文)。 我在 Windows 8 上使用 VC++12 进行编译

与我合作的文档: NTPClient

#include <iostream>
#include <stdexcept>

#include <Poco/Net/NTPClient.h>

using namespace Poco::Net;

int main()
{
    try {
        NTPClient client { IPAddress::Family::IPv4 };

             // this is where the bad_alloc comes from:
        client.request("129.6.15.30:123");  // or any other server

    }
    catch (std::exception& e) {
        std::cerr << e.message() << '\n';
    }
}

我不知道为什么这段代码会导致 bad_alloc 异常或访问冲突,所以我希望有人能指出我做错了什么。 我怀疑这是图书馆中的一个错误,我可能只是用错了(也许是?)。

更新 我有时也会收到“...0xC0000005:访问冲突读取位置 0x00E22CA9”。 (第二个内存位置不同)。但是,根据 IP 地址,有时仍会捕获 bad_alloc 错误(没有崩溃)。 因此,对于某些 IP,它会因访问冲突而崩溃,而某些 IP 会引发 bad_alloc 异常并终止。不知道那条信息是否有用。 此外,即使我将完整的垃圾作为 IP 地址提供,它们也会发生错误,例如“foobar”。

在有人有想法之前,我会检查来源并尝试找到一些东西(尽管以我的经验水平来说这很难)。

Update2:将库设置为调试库后(我想要更多信息,想要添加 PocoNetd.pdb(我认为它也允许 VS 调试 pocos 代码?)它不再发生......奇怪,编程好奇怪……

【问题讨论】:

  • Poco 是一个不成熟的库。它很可能有一个错误,尤其是在 Windows 上。您必须调试并查看 bad_alloc 是从哪里抛出的。
  • @Puppy 感谢您指出这一点,实际上在我添加 try 块后它确实捕获了异常,谢谢,我错过了,会更正它。
  • @Collin Dauphinee:你能解释一下POCO“不成熟”的标准是什么吗?
  • 顺便说一句,如果您正在混合发布和调试库(显然您这样做),您可能会遇到奇怪的行为。如果您将使用不同 VS 版本编译的二进制文件混合在一起,也是一样。
  • 如果您找到了解决方案,请将其写为答案。不要在问题中提出解决方案。

标签: c++ network-programming ntp poco-libraries


【解决方案1】:

我在这里找不到 POCO 的问题。但是发布的代码存在问题 - 没有 std::exception::message() 这样的东西,因此代码无法编译。将 message() 更改为 what() 并执行,得到“找不到主机”异常描述。将 NTP 服务器更改为“pool.ntp.org”,它执行得很好。这是在 Windows 8、VS2013、64 位构建上运行良好的代码:

#include <iostream>
#include <stdexcept>
#include <Poco/Net/NTPClient.h>
using namespace Poco::Net;

int main()
{
    try {
        NTPClient client{ IPAddress::Family::IPv4 };
        client.request("pool.ntp.org");
    }
    catch (std::exception& e) {
        std::cerr << e.what() << '\n';
    }
}

编辑:原始代码中“找不到主机”异常的原因是因为端口嵌入在传递给 request() 调用的字符串中,但实现 hard codes 端口并且只需要 IP 地址或主机名.

EDIT2:只是一个建议:如果您的目标是运行调试二进制文件,那么您可能认为您的问题已解决。否则,您应该能够使用 POCO 库的发布版本构建和运行应用程序的发布版本。有关如何执行此操作的示例,请查看任何 Poco::Net sample VS projects 设置。

【讨论】:

  • 是的,我相信问题可能在于,您使用 IP 和 :port?无论如何,出于某种原因更改库解决了我的问题,我已经完成了一个输出服务器和本地时间的程序(但没有考虑延迟等)
  • 端口在内部是硬编码的,因此不应在字符串中指定。但是您可以将其作为 SocketAddress 传递。无论如何,正如我对您的 OP 所评论的那样,混合发布和调试库会导致问题。要么使用全部版本,要么全部调试,始终来自相同的编译器版本。
  • 我也尝试了一个 IP 地址(在检查源代码时看到了这个确切的东西之后),但是我得到了同样的错误。然后我开始喂完整的垃圾值,它仍然是一样的。所以我认为错误与请求的错误参数无关(它没有,它抛出 HostNotFoundException 或 smth)
【解决方案2】:

在将库设置为调试库之后(我想要更多信息,想要添加 PocoNetd.pdb(我认为它也允许 VS 调试 pocos 代码?)它不再发生......奇怪,编程很奇怪... 我也能够如此成功地编译并运行一个发布版本。

简而言之:我搞砸了我的设置,但 POCO 对我来说却完美无缺。有趣的是,搞砸 Debug/Release 会出现什么样的错误。

【讨论】: