Implemented changes to substantially reflect the Networking Library Proposal (N4370).
New Executor type requirements and classes to support an executor framework, including the execution_context base class, the executor_work class for tracking outstanding work, and the executor polymorphic wrapper. Free functions dispatch(), post() and defer() have been added and are used to submit function objects to executors.
Completion handlers now have an associated executor and associated allocator. The free function wrap() is used to associate an executor with a handler or other object. The handler hooks for allocation, invocation and continuation have been deprecated.
A system_executor class has been added as a default executor.
The io_service class is now derived from execution_context and implements the executor type requirements in its nested executor_type class. The member functions dispatch(), post(), defer() and wrap() have been deprecated. The io_service::work class has been deprecated.
The io_service member function reset() has been renamed to restart(). The old name is retained for backward compatibility but has been deprecated.
The make_service<>() function is now used to add a new service to an execution context such as an io_service. The add_service() function has been deprecated.
A new strand<> template has been added to allow strand functionality to be used with generic executor types.
I/O objects (such as sockets and timers) now provide access to their associated io_service via a context() member function. The get_io_service() member function is deprecated.
All asynchronous operations and executor operations now support move-only handlers. However, the deprecated io_service::post(), io_service::dispatch(), io_service::strand::post() and io_service::strand::dispatch() functions still require copyable handlers.
Waitable timer objects are now movable.
Waitable timers, socket iostreams and socket streambufs now provide an expiry() member function for obtaining the expiry time. The accessors expires_at() and expires_after() have been deprecated, though those names are retained for the mutating members.
The std::packaged_task class template is now supported as a completion handler. The initiating operation automatically returns the future associated with the task. The package() function has been added as a convenient factory for packaged tasks.
Sockets, socket acceptors and descriptors now provide wait() and async_wait() operations that may be used to wait for readiness. The null_buffers type has been deprecated.
The proposed error code enum classes are simulated using namespaces. Existing asio error codes now have a correspondence with the standard error conditions.
Conversion between IP address types, and conversion from string to address, is now supported via the address_cast<>(), make_address(), make_address_v4() and make_address_v6() free functions. The from_string(), to_v4(), to_v6() and v4_mapped() member functions have been deprecated.
A default-constructed ip::address now represents an invalid address value that is neither IPv4 nor IPv6.
New buffer() overloads that generate mutable buffers for non-const string objects.
Support for dynamic buffer sequences that automatically grow and shrink to accomodate data as it is read or written. This is a generic facility similar to the existing asio::streambuf class. This support includes:
New dynamic_string_buffer and dynamic_vector_buffer adapter classes that meet the DynamicBufferSequence type requirements.
New dynamic_buffer() factory functions for creating a dynamic buffer adapter for a vector or string.
New overloads for the read(), async_read(), write() and async_write(), read_until() and async_read_until() free functions that directly support dynamic buffer sequences.
Support for networks and address ranges. Thanks go to Oliver Kowalke for contributing to the design and providing the implementation on which this facility is based. The following new classes have been added:
address_iterator_v4 for iterating across IPv4 addresses
address_iterator_v6 for iterating across IPv6 addresses
address_range_v4 to represent a range of IPv4 addresses
address_range_v6 to represent a range of IPv6 addresses
network_v4 for manipulating IPv4 CIDR addresses, e.g. 1.2.3.0/24
network_v6 for manipulating IPv6 CIDR addresses, e.g. ffe0:/120
New convenience headers in <asio/ts/*.hpp> that correspond to the headers in the proposal.
просто оставлю это тут.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Когда они сделают возможность закрыть сокет, и дождаться завершения всех асинхронных хэндлеров по нему без тонны костылей и/или без остановки io_service? Это же просто ужас какой-то!
Здравствуйте, fdn721, Вы писали:
F>Да зачем оно там нужно в таком виде???
F>Когда они сделают возможность закрыть сокет, и дождаться завершения всех асинхронных хэндлеров по нему без тонны костылей и/или без остановки io_service? Это же просто ужас какой-то!
Здравствуйте, о_О, Вы писали:
о_О>ну, ты эта, не массив сортируешь... о_О>асинхронные вещи требуют асинхронного управления. вся asio — костыль, но твой пример хреновый аргумент против.
С асинхронными вещами трудно работать. Иногда нужно просто выполнить несколько несложных операций, а они навязывают тебе целую идеологию и архитектуру.
Мне вот непонятно почему не предусмотреть простой механизм, который бы позволил дождаться завершения всех асинхронных операций по сокету. Это бы решило кучу проблем.
И вообще во всей документации и примерах по ASIO старательно умалчивают про корректное завершение работы.
У них там бесконечный цикл в main, а все данные обрабатываются прямо в классе клиента. А как только ты начинаешь взаимодействовать из клиент с остальными частями программы, опять возникает куча проблем.
Я не против того что так устроена сторонняя библиотека ASIO, но тащить непродуманное решение в стандарт я бы не стал.
Здравствуйте, niXman, Вы писали:
X>Implemented changes to substantially reflect the Networking Library Proposal (N4370).
Boost.Asio была предложена ещё в 2006 году в рамках TR2.
Здравствуйте, fdn721, Вы писали:
F>С асинхронными вещами трудно работать. Иногда нужно просто выполнить несколько несложных операций, а они навязывают тебе целую идеологию и архитектуру.
Именно поэтому сейчас продвигают resumable functions (async/await) как помощь в решении проблем с асинхронностью.
Здравствуйте, fdn721, Вы писали:
F>А как? Ну вот к примеру стандартная ситуация:
[здесь был код] F>Как с этим бороться без кучи костылей???
Общепринятый подход показан в примерах к Boost.asio — положиться на подсчет ссылок в shared_ptr, передавать shared_ptr вместо this в асинхронные обработчики. Тогда при завершении последнего обработчика, объект будет удален.
class MyClient : public boost::enable_shared_from_this<MyClient>
{
protected:
tcp::socket m_socket;
public:
bool Open()
{
....
m_socket.async_connect( m_endpoint, boost::bind( &MyClient::HandleConnect, shared_from_this(), _1 ) );
}
void Close()
{
m_socket.close()
}
protected:
void HandleConnect( const boost::system::error_code& err )
{
//do somthing
}
}
int main()
{
...
boost::shared_ptr<MyClient> client = boost::make_shared<MyClient>();
client->Open();
client->Close(); //<<---- Тут ASIO запланирует вызов HandleConnect со значением error::operation_aborted.
// delete client; //<<---- не нужно, объект будет удален, когда на него не останется ссылок
...
}
Здравствуйте, PM, Вы писали:
PM>Общепринятый подход показан в примерах к Boost.asio — положиться на подсчет ссылок в shared_ptr, передавать shared_ptr вместо this в асинхронные обработчики. Тогда при завершении последнего обработчика, объект будет удален.
Да видел я все эти примеры, только они все однотипные. Вся обработка идёт внутри этого самого "MyClient". Только я не эхо сервер/клиент пишу. А как только начинаешь взаимодействовать из MyClient с остальной частью программы вылезают все те же самые проблемы с кучей асинхронных операций, которые невозможно просто взять и завершить.
ЗЫ По началу кажется что ASIO это очень мощное решение, а по факты всегда всё сводится к одному подходу. Шаг влево, шаг в право и у тебя куча проблем.
Здравствуйте, fdn721, Вы писали:
F>Да видел я все эти примеры, только они все однотипные. Вся обработка идёт внутри этого самого "MyClient". Только я не эхо сервер/клиент пишу. А как только начинаешь взаимодействовать из MyClient с остальной частью программы вылезают все те же самые проблемы с кучей асинхронных операций, которые невозможно просто взять и завершить.
F>ЗЫ По началу кажется что ASIO это очень мощное решение, а по факты всегда всё сводится к одному подходу. Шаг влево, шаг в право и у тебя куча проблем.
В вашем примере кода была обычная проблема со временем жизни объекта, которая решается обычным способом
Проблемы будут с asio, как и с какой-то другой библиотекой асинхронности, потому что асинхронность это сложно. И часто асинхронность используют еще и многопоточной среде, что только добавляет сложности.
Может быть я ошибаюсь, и есть альтернативы Asio? Я немного работал с libuv, там тоже не все просто.
PM>Проблемы будут с asio, как и с какой-то другой библиотекой асинхронности, потому что асинхронность это сложно. И часто асинхронность используют еще и многопоточной среде, что только добавляет сложности.
В asio сама реализация асинхронности занимает наименьшую часть кода. И это самая простая часть кода. Всё остальное-это
врайперы, сводящие воедино кучи интерфейсов и куч ОСей.
PM>Может быть я ошибаюсь, и есть альтернативы Asio? Я немного работал с libuv, там тоже не все просто.
Если нет требоавания кроссплатформа, то писать на нативном API ОС, будет проще, чем разбираться с
фантазиями создателей asio.
Здравствуйте, fdn721, Вы писали:
F>А как? Ну вот к примеру стандартная ситуация: F>Как с этим бороться без кучи костылей???
Кстати, можно использовать синхронные варианты
Здравствуйте, smeeld, Вы писали:
S>Если нет требоавания кроссплатформа, то писать на нативном API ОС, будет проще, чем разбираться с S>фантазиями создателей asio.
Только в результате получится еще одно ASIO реализующее фантазии другого автора, только более глючное, так как в отладку вложить сопоставимые ресурсы будет трудно. Не нравится ASIO – возьми другую библиотеку по вкусу, благо альтернатив очень много.
Здравствуйте, fdn721, Вы писали:
F>Да видел я все эти примеры, только они все однотипные. Вся обработка идёт внутри этого самого "MyClient". Только я не эхо сервер/клиент пишу. А как только начинаешь взаимодействовать из MyClient с остальной частью программы вылезают все те же самые проблемы с кучей асинхронных операций, которые невозможно просто взять и завершить.
проверить в этой "куче асинхронных операций" error::operation_aborted религия не позволяет?