Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [POCO] HTTPClientSession на x64 
V
    Опции темы
cupper
Дата 19.9.2011, 18:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: 1
Всего: 1



Столкнулся с таким весьма странным поведением.

В начале приложения создается сессия
Код

Poco::URI uri(properties_.host_);
        uri.setPort(properties_.port_);
        uri_ = uri;
        ptrContext_ = new Context(Context::CLIENT_USE, "", "", "", Context::VERIFY_NONE);
        session_.reset(new HTTPSClientSession(uri_.getHost(), uri_.getPort(), ptrContext_));

         if (properties_.keepAliveTimeout_)
        {
            session_->setKeepAlive(true);
            session_->setKeepAliveTimeout(Timespan(properties_.keepAliveTimeout_, 0));
        }


Далее есть процедура в которой создается хедер
Код

HTTPRequest req_post(HTTPRequest::HTTP_POST, properties_.uri_);
req_post.setVersion(HTTPRequest::HTTP_1_1);
        req_post.setContentType("text/xml");
        req_post.setContentLength(msg.size());
        req_post.set("User-Agent","bla");
        if (properties_.keepAliveTimeout_) req_post.setKeepAlive(true);
        req_post.set("Keep-Alive", "timeout=" + ((properties_.keepAliveTimeout_ > 0) ? i2str(properties_.keepAliveTimeout_) : string("5"))
            + ", max=" + i2str(properties_.keepAliveTimeout_));
        if (!cookies_.empty())
            req_post.setCookies(cookies_);

        if (!properties_.login_.empty())
        {
            HTTPBasicCredentials cred(properties_.login_, properties_.password_);
            cred.authenticate(req_post);
            assert (req_post.hasCredentials());
        }


и проиходит отправка мессаги
Код

session_->sendRequest(req_post) << msg;


Так вот. При запуске на x32 системе все работает корректно.
При запуске на x64 система наблюдается следующее поведение.

Первая мессага отправляется. Далее если отправлять мессаги следом то они отправляються так же корректно. Но если между отправкой мессаг есть интервал > 10 - 15 секунду, то строчка
Код

session_->sendRequest(req_post) << msg;


вызывает эксцепшен ConnectionAbortedException с текстом "Software caused connection abort".
Это определение эксцепшена из Poco.
Код

POCO_IMPLEMENT_EXCEPTION(ConnectionAbortedException, NetException, "Software caused connection abort")


Если же проглотить этот эксцепшен и опять сделать вызов
Код

session_->sendRequest(req_post) << msg;

то в этот раз мессага отправиться нормально.

Я в полном недоумении.

PM MAIL   Вверх
Alca
Дата 19.9.2011, 18:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 7
Всего: 50



Ну так глянь сорцы


--------------------
PM WWW ICQ Skype Jabber   Вверх
cupper
Дата 21.9.2011, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: 1
Всего: 1



Совсем странные вещи творятся в сорцах Poco. Методом упорной правки сорцов поко, перебилда, перезапуска, локализовал место возникновения экцепшена.

в функции sendRequest(req_post)

при задержке более keepAlive происходит закрытие сокеты и его повторное открытие.
Так вот в момент закрытия сокета

Код

std::ostream& HTTPClientSession::sendRequest(HTTPRequest& request)
{
    delete _pResponseStream;
    _pResponseStream = 0;

    bool keepAlive = getKeepAlive();
    if ((connected() && !keepAlive) || mustReconnect())
    {
        try
        {
        close();
        }
        catch(std::exception &ex)
        {
            std::string err = ex.what();
            err += " sendRequest()->close()";
            throw Exception(err);
        }
        _mustReconnect = false;
    }


блоки try catch добавлены уже мною в процессе локализации места возникновения ошибки. 
При вызове функции close() которая является просто врапером
Код

void HTTPSession::close()
{
    _socket.close();
}

которая опять таки тоже врапер на функцию
Код

inline void Socket::close()
{
    _pImpl->close();
}

вызывается функция
Код

void SocketImpl::close()
{
    if (_sockfd != POCO_INVALID_SOCKET)
    {
        poco_closesocket(_sockfd);
        _sockfd = POCO_INVALID_SOCKET;
    }
}

где poco_closesocket() девайн на системную функцию
Код

#define poco_closesocket(s)  closesocket(s)


так вот. если все тело функции SocketImpl::close() обернуть в блок try catch то в ней исключение не возникает. НО в функции Socket::close() которая вызывает функцию SocketImpl::close() возникает исключение которое ловиться на самом верху. 

Вопрос: как это возможно ?

Проверить в нормально дебаге нет возможность, поэтому я и вставляю везде блоки try catch, после чего пересобираю poco, после чего пересобираю свою програмулину, и переношу и запускаю на другой системе. Поэтому я допускаю возможность что я упустил чтото тривиальное, но балин, ЧТО, я по косточкам разобрал стек вызовов, нету там больше ничего, но исключение возникает, и хоть убейся я не понимаю где и почему.
PM MAIL   Вверх
cupper
Дата 21.9.2011, 12:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: 1
Всего: 1



и конечно же в тестовом примере это не воспроизводится. Правда тестовый пример был просто на http.
Поэтому продебажить нормально возможности нет.

Как можно узнать что и откуда бросило исключение ? И что бы в релизной сборке работало это ?
PM MAIL   Вверх
Alca
Дата 21.9.2011, 13:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 7
Всего: 50



эссертами не пользуешься?


--------------------
PM WWW ICQ Skype Jabber   Вверх
cupper
Дата 22.9.2011, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: 1
Всего: 1



Цитата(Alca @ 21.9.2011,  13:29)
эссертами не пользуешься?

пользуюсь. Правда не понял к чему вы.

Переустановил систему на x64, пересобираю либы, буду пробовать снова. 
PM MAIL   Вверх
Alca
Дата 22.9.2011, 11:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 7
Всего: 50



Цитата

Правда не понял к чему вы.

К тому, что надо проверять, анализировать то, что вернула какая-либо функция

Это сообщение отредактировал(а) Alca - 22.9.2011, 11:55


--------------------
PM WWW ICQ Skype Jabber   Вверх
cupper
Дата 27.9.2011, 21:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: 1
Всего: 1



Цитата(Alca @ 22.9.2011,  11:54)
Цитата

Правда не понял к чему вы.

К тому, что надо проверять, анализировать то, что вернула какая-либо функция

либа возвращала эксцепшен из пустого места, я хз что тут модно асертом проверить. Я все что можно позатыкал try catch блоками, но оно мезду ними умудрялось возникать. В итогде была була установленна x64 система, пересобраны либы, и... эксцепшен перестал возникать. 
PM MAIL   Вверх
Alca
Дата 27.9.2011, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 7
Всего: 50



Цитата

из пустого места

веришь в чудеса?


--------------------
PM WWW ICQ Skype Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0484 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.