Сокеты Windows. Блокировка

В этой статье и двух дополнительных статьях объясняется несколько проблем программирования сокетов Windows. В этой статье рассматривается блокировка. Другие проблемы рассматриваются в статьях: сокеты Windows: упорядочение байтов и сокетов Windows: преобразование строк.

Если вы используете или извлекаете из класса CAsyncSocket, вам потребуется самостоятельно управлять этими проблемами. При использовании или производных от класса CSocket MFC управляет ими.

Блокировка

Сокет может находиться в режиме блокировки или в режиме неблокировки. Функции сокетов в режиме блокировки (или синхронного) не возвращаются, пока они не смогут завершить свое действие. Это называется блокировкой, так как сокет, функция которого была вызвана, не может ничего делать — блокируется, пока вызов не возвращается. Например, вызов Receive функции-члена может занять произвольное время, так как оно ожидает отправки приложения (это если вы используете CSocketили используете CAsyncSocket с блокировкой). CAsyncSocket Если объект находится в режиме неблокировки (работает асинхронно), вызов возвращается немедленно и текущий код ошибки, извлекаемый с помощью функции-члена GetLastError, — WSAEWOULDBLOCK, указывающий, что вызов не вернулся бы немедленно из-за режима. (CSocket никогда не возвращает WSAEWOULDBLOCK. Класс управляет блокировкой для вас.)

Поведение сокетов отличается от 32-разрядных и 64-разрядных операционных систем (таких как Windows 95 или Windows 98), чем в 16-разрядных операционных системах (таких как Windows 3.1). В отличие от 16-разрядных операционных систем, 32-разрядные и 64-разрядные операционные системы используют предварительное многозадачность и обеспечивают многопоточность. В 32-разрядных и 64-разрядных операционных системах можно поместить сокеты в отдельные рабочие потоки. Сокет в потоке может блокироваться, не вмешиваясь в другие действия в приложении и не тратя время вычислений на блокировку. Сведения о многопоточных программированиях см. в статье "Многопоточность".

Примечание.

В многопоточных приложениях можно использовать блокирующий характер CSocket для упрощения проектирования программы, не влияя на скорость реагирования пользовательского интерфейса. Обрабатывая взаимодействие пользователей в основном потоке и CSocket обработке в альтернативных потоках, вы можете разделить эти логические операции. В приложении, которое не является многопоточным, эти два действия должны быть объединены и обрабатываться как один поток, что обычно означает использование, CAsyncSocket которое позволяет обрабатывать запросы на обмен данными по запросу или переопределять CSocket::OnMessagePending для обработки действий пользователей во время длительной синхронной активности.

Остальная часть этого обсуждения предназначена для программистов, предназначенных для 16-разрядных операционных систем:

Как правило, при использовании CAsyncSocketследует избегать использования блокирующих операций и асинхронно работать. В асинхронных операциях с точки, в которой вы получаете код ошибки WSAEWOULDBLOCK после вызоваReceive, например, дождитесь OnReceiveвызова функции-члена, чтобы уведомить вас о том, что вы можете снова прочитать. Асинхронные вызовы выполняются путем вызова соответствующей функции уведомления обратного вызова сокета, например OnReceive.

В Windows блокировка вызовов считается плохой практикой. По умолчанию CAsyncSocket поддерживает асинхронные вызовы, и вам необходимо самостоятельно управлять блокировкой с помощью уведомлений обратного вызова. С другой стороны, класс CSocket синхронен. Он насосирует сообщения Windows и управляет блокировкой для вас.

Дополнительные сведения о блокировке см. в спецификации сокетов Windows. Дополнительные сведения о функциях "On" см. в статье "Сокеты Windows: уведомления сокетов и сокеты Windows: производные от классов сокетов".

Дополнительные сведения см. в разделе:

См. также

Сокеты Windows в MFC
CAsyncSocket::OnSend