Студопедия
Главная страница | Контакты | Случайная страница

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Блокирующий режим

Читайте также:
  1. III. Государственный (политический) режим.
  2. L. Дисциплинарный режим
  3. X исправительной колонии особого режима
  4. А) временный режим;
  5. Авторитарний режим
  6. Авторитарный политический режим. Характерные черты и виды.
  7. Адаптация к влажности и водному режиму.
  8. Административно-правовой режим военного положения.
  9. Административно-правовой режим чрезвычайного положения.
  10. Безопасный режим в Windows 8 и Windows 8.1

При блокировке сокета необходима осторожность, так как этом режиме лю­бой вызов функции Winsock именно блокирует сокет на некоторое время. Большинство приложений Winsock следуют модели «поставщик — потреби­тель», в которой программа считывает или записывает определенное количе­ство байт и затем выполняет с ними какие-либо операции.

 

SOCKET sock;

char buff[256];

int done = 0;

while(!done) {

nBytes = recv(sock, buff, 65);

if (nBytes == SOCKET_ERROR) {

printf("recv failed with error %d\n", WSAGetLastError());

return;

}

DoComputationOnData(buff);

}

 

Проблема в том, что функция recv может не завершиться никогда, так как для этого нужно считать какие-либо данные из буфера системы. В такой си­туации некоторые программисты могут соблазниться «подглядыванием» данных (чтение без удаления из буфера), используя флаг MSG_PEEK в recv или вызывая ioctlsocket с параметром FIONREAD. Подобный стиль програм­мирования заслуживает резкой критики. Издержки, связанные с «подгляды­ванием», велики, так как необходимо сделать один или более системных вы­зовов для определения числа доступных байт, после чего все равно прихо­дится вызывать recv для удаления данных из буфера.

Чтобы этого избежать, следует предотвратить замораживание приложе­ния из-за недостатка данных (из-за сетевых проблем или проблем клиента) без постоянного «подглядывания» в системные сетевые буферы. Один из ме­тодов — разделить приложения на считывающий и вычисляющий потоки, совместно использующие общий буфер данных. Доступ к буферу регулиру­ется синхронизирующим объектом, таким как событие или мьютекс. Задача считывающего потока — постоянно читать данные из сети и помещать их в общий буфер. Считав минимально необходимое количество данных, этот поток инициирует сигнальное событие, уведомляющее вычисляющий поток, что можно начинать вычисления. Затем вычисляющий поток удаля­ет часть данных из буфера и производит с ними необходимые операции. В следующем листинге реализованы две функции: для приема данных (ReadThread) и их обработки (ProcessThread).

 

// Перед созданием двух потоков,

// инициализируется общий буфер (data)

// и создается сигнальное событие (hEvent)

CRITICAL_SECTION data;

HANDLE hEvent;

TCHAR buff[MAX_BUFFER_SIZE];

int nbytes;

// Считывающий поток void ReadThread(void) {

int nTotal = 0, nRead = 0, nLeft = 0 nBytes = 0;

while (!done)

{

nTotal = 0;

nLeft = NUM_BYTES_REQUIRED;

while (nTotal!= NUM_BYTES_REQUIRED)

{

EnterCriticalSection(&data);

nRead = recv(sock, &(buff[MAX_BUFFER_SIZE - nBytes]), nLeft);

if (nRead == -1) {

printf("error\n"); ExitThread();

nTotal += nRead;

nLeft -= nRead;

 

nBytes += nRead;

LeaveCriticalSection(&data);

}

SetEvent(hEvent); } }

// Вычисляющий поток void ProcessThread(void)

WaitForSingleObject(hEvent);

EnterCriticalSection(&data);

DoSomeComputationOnData(buff);

// Удаление обработанных данных из буфера

// и сдвиг оставшихся в начало массива

nBytes -= NUM BYTES REQUIRED;

}

LeaveCriticalSection(&data);

}

 

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




Дата добавления: 2014-12-19; просмотров: 74 | Поможем написать вашу работу | Нарушение авторских прав




lektsii.net - Лекции.Нет - 2014-2025 год. (0.007 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав