Шаг 31 - Масштабируемые сетевые приложения на основе Socket продолжение

В Winnt/Win2000 драйвером Winsock который предоставляет эмуляцию сокетов является драйвер AFD.SYS. Он отвечает за соединения и управлением буфера. Он работает с более низкими драйверами протоколов. К примеру, когда мы вызываем WSASend для посылки данных, на самом деле этот драйвер копирует данные во внутренний буфер и посылает их или WSASend возвращается немедленно. Конечно если приложение хочет послать данные которые не влезают в буфер, то тогда WSASend блокирует дальнейшее выполнение вызвавшего его блока, пока не отошлёт все данные.

Точно также, когда принимаем данные, сперва они копируются в буфер. Затем когда приложение вызывает WSARecv, они копируются из буфера драйвера AFD.SYS в буфер приложения.

В большинстве случаев это работает хорошо. В особенности это хорошо для тех приложений которые используют стандартные принципы работы с сокетами с не перекрывающимися вызовами послал, принял и т.д. Программист должен понимать, что произойдёт при отключении буферов для приёма и посылки(с помощью функции WSPGetSockOpt, они устанавливаются в 0; используются SO_SNDBUF и SO_RCVBUF)

К примеру рассмотрим случай когда приложение установило SO_RCVBUF в 0 и использует блокирующий сокет. Никакого выигрыша в производительности мы не получим. В этом случае буфер приложения блокируется ядром и Send API не вернётся пока другой конец соединения не подтвердит заполнения буфера. Возможно будет казаться, что этот способ хорош, чтобы определить, что данные приняты другой стороной, но это не так. Даже подтверждение другой стороной, что TCP пакеты приняты не гарантирует, что они приняты приложением так как там может не хватить ресурсов. Практически проблема состоит в том, что ваше приложение не может посылать одновременно несколько "пакетов" в одном потоке. То есть ждёт пока не отослался пакет, прежде чем послать другой.


Предыдущий Шаг | Оглавление
Автор Leonid Molochniy - 15.12.2001