«Нарушение прав доступа», «неверное распределение»: запрос POCO NTPClient C++

Я хотел сделать простую программу, которая делает следующее: «Получить атомное время из интернет-часов». Я уже сделал другую программу, которая использует FTP, и я сделал это с библиотекой Poco::Net.

Я попытался использовать NTPClient, так как я читал, что это сетевой протокол времени. Более подробно вот информация, с которой я работал:

«Серверы NIST прослушивают запрос NTP на порту 123 и отвечают, отправляя пакет данных udp/ip в формате NTP. Пакет данных включает 64-битную метку времени, содержащую время в секундах UTC с 1 января 1900 года с разрешением 200 пс».

Моим источником является этот веб-сайт: nist

Кроме того, я пробовал различные серверы отсюда, которые имели статус «все службы доступны»: серверы< /а>

Вот небольшой пример, который дает сбой и/или выдает исключение. Это исключение std::bad_alloc и иногда происходит сбой с "нарушением прав доступа" (см. ниже). Я компилирую с помощью VC++12 в Windows 8.

Документы, с которыми я работал: 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-адресов он вылетает с нарушением прав доступа, а для некоторых выдает исключение bad_alloc и завершает работу. Не знаю, может ли эта информация быть полезной. Кроме того, возникает ошибка, даже если я подаю полный мусор в качестве IP-адреса, например. "фубар".

Пока у кого-то не появится идея, я изучу исходники и попытаюсь что-нибудь найти (хотя с моим уровнем опыта это сложно).

Обновление 2: после настройки библиотек для отладки библиотек (мне нужна была дополнительная информация, я хотел добавить PocoNetd.pdb (я думаю, что это позволяет VS также отлаживать код pocos?), это больше не происходит ... странно, программирование - это странно. ..


person smoothware    schedule 31.12.2014    source источник
comment
Poco — незрелая библиотека. Там вполне может быть ошибка, особенно в Windows. Вам придется отладить и посмотреть, откуда выбрасывается bad_alloc.   -  person Collin Dauphinee    schedule 31.12.2014
comment
@Puppy спасибо, что указали на это, на самом деле он поймал исключение после того, как я добавил блок try, спасибо, я пропустил это и исправлю.   -  person smoothware    schedule 01.01.2015
comment
@Collin Dauphinee: не могли бы вы объяснить, по каким критериям POCO незрелый?   -  person Alex    schedule 01.01.2015
comment
Кстати, если вы смешиваете выпускные и отладочные библиотеки (что, очевидно, вы и делаете), вы, вероятно, столкнетесь со странным поведением. То же самое, если вы смешиваете двоичные файлы, скомпилированные с разными версиями VS.   -  person Alex    schedule 01.01.2015
comment
Если вы нашли свое решение, напишите его как ответ. Не помещайте решения в вопрос.   -  person Lightness Races in Orbit    schedule 01.01.2015


Ответы (2)


Я не смог найти здесь проблему с 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(), но реализация жестко кодирует порт и ожидает только IP-адрес или имя хоста.

EDIT2: Просто совет: если ваша цель - запустить отладочные двоичные файлы, вы можете считать свою проблему решенной. В противном случае вы сможете собрать и запустить выпускную сборку своего приложения с выпускными версиями библиотек POCO. Пример того, как это сделать, можно найти в любом из примеров Poco::Net VS. проекты настройки.

person Alex    schedule 01.01.2015
comment
да, я думаю, может быть, проблема была в том, что вы использовали IP-адрес с :port? В любом случае, изменение библиотек по какой-то причине решило мою проблему, я уже закончил программу, которая выводит серверное и местное время (однако не принимая во внимание задержку или что-то в этом роде) - person smoothware; 01.01.2015
comment
Порт жестко запрограммирован внутри, поэтому его не следует указывать в строке. Но вы могли бы передать его как SocketAddress. В любом случае, как я прокомментировал ваш OP, смешивание выпускных и отладочных библиотек вызовет проблемы. Либо используйте всю версию, либо всю отладку, всегда из одной и той же версии компилятора. - person Alex; 01.01.2015
comment
Я также попробовал только IP-адрес (после того, как увидел именно это при проверке источников), однако получил те же ошибки. Затем я начал скармливать полные значения мусора, и все было так же. Итак, я решил, что ошибка не имеет ничего общего с неверным аргументом для запроса (чего не было, он выдает HostNotFoundException или что-то в этом роде) - person smoothware; 02.01.2015

После настройки библиотек для отладки библиотек (мне нужна была дополнительная информация, я хотел добавить PocoNetd.pdb (я думаю, это позволяет VS также отлаживать код pocos?), этого больше не происходит... странно, программирование - это странно... Я также могу так успешно скомпилировать и запустить релизную версию.

Итак, в двух словах: я испортил свои настройки, и POCO все же работал у меня безупречно. Интересно, какие ошибки вы получите, перепутав Debug/Release.

person smoothware    schedule 02.01.2015