2016-02-02 5 views
1

Возможно ли использовать asio для Boost as non-blocking IO без использования асинхронных обратных вызовов? I.e. что эквивалентно опции разъема O_NONBLOCK.Boost asio non-blocking IO без обратных вызовов

Я в принципе хочу эту функцию:

template<typename SyncWriteStream, 
     typename ConstBufferSequence> 
std::size_t write_nonblock(
    SyncWriteStream & s, 
    const ConstBufferSequence & buffers); 

Эта функция будет писать столько байт, как это может и немедленно вернуться. Он может писать 0 байт.

Возможно ли это?

+0

* Как * он мог «вернуть» количество байтов, записанных, если оно немедленно возвращается? Как бы вы могли узнать, были ли отправлены данные или нет? Если есть ошибки? Это невозможно без каких-либо обратных вызовов. –

+0

Он записывает их во внутренний буфер. Взгляните на 'O_NONBLOCK'. – Timmmm

+0

Я знаю о неблокирующих сокетах, интересно, как бы вы сказали программе, что вызов 'write' преуспел или не удался, если вы не хотите использовать обратные вызовы. И как бы вы даже знали, когда функция 'write' была закончена без какого-либо опроса? Вы сделаете это в основной программе? Опросить какой-то буфер состояния? Асинхронное программирование не так просто, как «вызов неблокирующей функции, а затем продолжить мой веселый путь». –

ответ

3

Да, используя метод non_blocking() поместить гнездо в неблокируемому режиме Asio:

template<typename SyncWriteStream, 
     typename ConstBufferSequence> 
std::size_t write_nonblock(
    SyncWriteStream & s, 
    const ConstBufferSequence & buffers) 
{ 
    s.non_blocking(true); 
    boost::system::error_code ec; 
    auto bytes = s.send(buffers, 0, ec); 
    if (bytes == 0 && !(ec == boost::asio::error::would_block)) 
     throw boost::system::system_error(ec, "write_nonblock send"); 
    return bytes; 
} 
+0

Могу ли я сделать то же самое во время чтения? Должен ли я установить 's.non_blocking (true)' перед каждым вызовом чтения или записи сокета? –

+1

@SegmentationFault да, вы можете использовать функцию 'receive' для выполнения одного чтения. Свойство 'non_blocking' сохраняется между вызовами, поэтому вам не нужно повторно вызывать' s.non_blocking (true) 'каждый раз. – ecatmur

-1

Путь с s.non_blocking(true) не будет работать. Если вы проверили send, то он использует socket_ops::sync_send, что делает poll_write, если отправка не удалась.

Таким образом, он все еще блокируется на верхнем уровне.

Смежные вопросы