LINUX.ORG.RU

Можно ли 2 (или 3) раза сделать запись в асинхронный сокет, не дождавшись пред. вызовов?

 , ,


1

2

Т.е. мы 3 раза в асинхр. сокет сделаем write. Так можно делать? Никакой ошибки не будет? А TCP данные не перепутаются у нас в этом случае?

Что есть асинхронный сокет? Неблокирующийся? Сделать то можно, но не факт, что данные запишутся. Нужно проверять после возврата из send() на ошибки EWOULDBLOCK и т.п.

Olegymous ★★ ()
Ответ на: комментарий от Olegymous

Так делать так или нет? Обязательно ждать пока результат предыдущего write не придет?

Да, неблокирующийся.

facelift ()
Последнее исправление: facelift (всего исправлений: 1)
Ответ на: комментарий от facelift

Разрешаю делать. А что за программа вообще? Event loop какой-нибудь используется? Обычно дожидаются, когда сокет станет доступен на запись и пишут туда пока не получат EWOULDBLOCK. И так по кругу.

Olegymous ★★ ()
Ответ на: комментарий от Olegymous

Да вот я думаю как быстрее сделать. На винде не IOCP, там можно сразу несколько раз вызвать. Я вот думаю получится или нет.

facelift ()
Ответ на: комментарий от facelift

Обязательно ждать пока результат предыдущего write не придет?

Не знаю, как там в Windows, но в Linux не приходит «результат предыдущего write». Ты получаешь событие, если в буфер записи можно писать. Никаких гарантий того, что предыдущие данные ушли.

Так делать так или нет?

Так делать можно. Считай, что пишешь в файл. Все записи будут друг за другом. Перепутаться они не могут.

i-rinat ★★★★★ ()

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

Elyas ★★★★★ ()

Асинхронный write это видимо aio_write или lio_listio. Они действительно только ставят запросы в очередь. И исполняться эти запросы будут в порядке очереди.

Неблокирующийся write не ставит в очередь. Он либо выполняет запись прямо сейчас не блокируясь (для tcp это означает, что есть место в буфере и ещё не заполнено окно), либо не выполняет её вовсе и возвращает ошибку EAGAIN.

Какое-либо переупорядочивание может возникнуть только если aio_write или write вызываются одновременно из нескольких потоков. Но это справедливо и для блокирующихся сокетов. При использовании нескольких потоков приложение должно само сериализовать вызовы aio_write/write в один файловый дескриптор.

iliyap ★★★★★ ()
Ответ на: комментарий от iliyap

Неблокирующийся write не ставит в очередь. Он либо выполняет запись прямо сейчас не блокируясь (для tcp это означает, что есть место в буфере и ещё не заполнено окно), либо не выполняет её вовсе и возвращает ошибку EAGAIN.

Забыл ещё - либо выполняет частично.

Sorcerer ★★★★★ ()

Да, без проблем, лишь бы свободного места в буфере сокета хватило. Данные из буфера уйдут в сеть тогда, когда смогут (да я Кэп), это может произойти в разные моменты времени, или вообще не произойти.

Скажу более, без спец настроек, ты можешь записать и сразу закрыть файловый дескриптор сокета, файловый дескриптор закроется, а сокет останется и будет доотсылать неотосланные данные.

pathfinder ★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.