Winsock WSAAsyncSelect отправка без бесконечного буфера - PullRequest
1 голос
/ 11 июня 2010

Это скорее вопрос дизайна, чем вопрос конкретного кода, я уверен, что упускаю очевидное, мне просто нужен другой набор глаз.

Я пишу многопользовательский сервер на основе WSAAsyncSelect, каждое соединение превращается в объект класса соединения, который я написал, который содержит соответствующие настройки, буферы и т. Д.

Мой вопрос касается FD_WRITE, я понимаю, как он работает: один FD_WRITE отправляется сразу после установления соединения. После этого вы должны отправлять до получения WSAEWOULDBLOCK, после чего вы сохраняете то, что осталось отправить в буфер, и ждете, когда вам сообщат, что отправлять снова можно.

Вот где у меня проблема, насколько большой я могу сделать этот буфер хранения в каждом объекте соединений? Время до получения нового FD_WRITE неизвестно, я мог пытаться отправить много материала в течение этого периода, все время добавляя в мой исходящий буфер. Если я сделаю буфер динамическим, использование памяти может выйти из-под контроля, если по какой-либо причине я не смогу отправить () и уменьшить буфер.

Итак, мой вопрос: как вы обычно справляетесь с этой ситуацией? Заметьте, я не говорю о самом сетевом буфере, который использует winsock, но о моем собственном создании, используемом для «отправки в очередь».

Надеюсь, я объяснил это достаточно хорошо, спасибо всем!

1 Ответ

0 голосов
/ 14 июня 2010

Естественно, правильный дизайн зависит от характера вашего приложения.

Некоторые программы могут предсказать объем данных, которые могут быть сгенерированы, прежде чем что-то делать с ними, поэтому они могут использовать фиксированный размербуфер.Например, один протокол, который я разработал, имел структуру «команда-ответ» и префикс длиной 2 байта, поэтому я мог использовать буферы 64 КБ и знать, что никогда их не переполну.Если буфер заполнен, программа должна ожидать ответа, прежде чем ей будет разрешено отправлять данные из этого буфера, поэтому в этот буфер больше не будет добавлено никаких данных.

Еще одно хорошее применение для буферов фиксированного размераэто когда данные поступают из другого источника ввода / вывода.Рассмотрим веб-сервер: по своей сути он отбрасывает файлы с диска и выплевывает их по проводам.Поэтому вы знаете, сколько вы читаете с диска за раз, так что вы знаете, насколько большими должны быть ваши буферы.

У меня возникают проблемы с поиском веской причины использовать динамические буферы.

Основная причина, по которой они вам не нужны - скользящее окно TCP .Если один из одноранговых подключений прекращает прием данных, стек удаленного однорангового узла прекращает отправку данных, когда окно TCP заполняется.Непрочитанные данные будут оставаться в буферах принимающего стека до тех пор, пока программа, в которую они были отправлены, не запросит их.Это дает приемнику возможность регулировать поступающие данные до уровня, который он может обработать.Насколько я могу судить, это делает буферы фиксированного размера практичными при любых условиях.

...