Как прочитать точное количество байтов из сокета потока (tcp)?

В winsock и синхронизация recv, и асинхронность WSARecv завершаются, как только в потоковом сокете появляются данные, независимо от указанного размера (это только верхний предел). Это означает, что для чтения фиксированного количества байтов из потока должна быть применена некоторая пользовательская буферизация. И если каждое чтение не буферизуется отдельно, это приводит к двойной буферизации, то есть фактически имеется два буфера на сокет.

Есть ли способ попросить winsock буферизовать данные от своего имени и завершить операцию только тогда, когда станет доступным указанное количество байтов (если не произойдет ошибка)?

EDIT: эта функция должна работать, в частности, для асинхронных сокетов.


person sold    schedule 15.11.2009    source источник


Ответы (1)


Для синхронных сокетов вы должны иметь возможность передать флаг MSG_WAITALL в recv, который будет блокироваться до тех пор, пока ваш буфер не заполнится или не произойдет ошибка/отключение.

Что касается перекрытий io, то не совсем. Ваш единственный реальный вариант - буферизовать данные. Однако для этого вам не нужны два буфера; вы можете использовать тот же буфер и просто передать буфер + смещение конца последнего чтения, пока буфер не будет заполнен.

person Gerald    schedule 15.11.2009
comment
Кажется, это решение для блокировки сокетов, но, согласно MSDN, оно не поддерживается для асинхронных сокетов. см. редактирование. - person sold; 16.11.2009