Проблема с Boost Asio асинхронного соединения с использованием C ++ в Windows - PullRequest
0 голосов
/ 24 февраля 2011

Используя MS Visual Studio 2008 C ++ для Windows 32 (бренд XP), я пытаюсь создать клиент POP3, управляемый из немодального диалогового окна.

Первый шаг - создать постоянный объект - скажем, pop3 - со всеми этими элементами Boost.asio для асинхронных подключений в сообщении WM_INITDIALOG процедуры диалогового окна. Некоторые как:

case WM_INITDIALOG:
    return (iniPop3Dlg (hDlg, lParam));

Здесь мы предполагаем, что iniPop3Dlg () создает объект кучи pop3 - скажем, на что указывает pop3p -. Затем подключитесь к удаленному серверу, и сессия будет инициирована с помощью идентификатора и пароля клиента (команды USER и PASS). Здесь мы предполагаем, что сервер находится в состоянии СДЕЛКИ.

Затем, в ответ на некоторый пользовательский ввод, процедура-диалоговое окно, вызовите соответствующую функцию. Скажи:

case IDS_TOTAL: //  get how many emails in the server
    total (pop3p);
    return FALSE;
case IDS_DETAIL:   // get date, sender and subject for each email in the server
    detail (pop3p);
    return FALSE;

Обратите внимание, что total () использует команду STAT POP3 для получения количества писем на сервере, тогда как detail () использует две команды последовательно; сначала STAT для получения суммы, а затем цикл с командой GET для получения содержимого каждого сообщения.

В качестве отступления: detail () и total () совместно используют одни и те же подпрограммы - процедуру обработки STAT - и после завершения обе оставляют сеанс как есть. То есть без закрытия соединения; сокет остается открытым и сервер находится в состоянии транзакции.

Когда в первый раз выбирается какой-либо параметр, все работает как положено, получая желаемые результаты. Но при втором шансе соединение зависает.

Более тщательная проверка показывает, что первый раз, когда заявление

socket_.get_io_service().run();

Используется, никогда не заканчивается.

Обратите внимание, что все процедуры асинхронной записи и чтения используют один и тот же io_service, и каждая подпрограмма использует socket_.get_io_service().reset() перед любым run()

Кроме того, во всех операциях R / W также используется один и тот же таймер, который сбрасывается до нуля, ожидая после завершения каждой операции:

dTimer_.expires_from_now (boost::posix_time::seconds(0));

Я подозреваю, что проблема в io_service или в таймере, и тот факт, что последующие исполнения происходят при другой загрузке подпрограммы.

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

1 Ответ

0 голосов
/ 24 февраля 2011

Вы смотрели на asio примеры и изучали их? Есть несколько асинхронных примеров, которые должны помочь вам понять основной поток управления. Обратите особое внимание на основной цикл событий, запускаемый с вызова io_service::run, важно понимать, что управление не должно возвращаться вызывающей стороне до тех пор, пока у io_service не останется больше работы.

...