Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье объясняется, как объект CSocket, объект CSocketFile и объект CArchive объединяются для упрощения отправки и получения данных через сокет Windows.
В статье Windows Sockets: Пример использования сокетов с архивами представлена PacketSerialize
функция. Объект архива в PacketSerialize
примере работает так же, как архивный объект, переданный в функцию сериализации MFC. Важное отличие заключается в том, что для сокетов архив присоединяется не к стандартному объекту CFile (обычно связанному с файлом диска), но к объекту CSocketFile
. Вместо подключения к файлу CSocketFile
диска объект подключается к объекту CSocket
.
Объект CArchive
управляет буфером. Когда буфер архива хранения (отправки) заполнен, связанный CFile
объект записывает содержимое буфера. Очистка буфера архива, подключенного к сокету, эквивалентна отправке сообщения. Когда буфер архива загрузки (получения) заполнен, CFile
объект перестает считывать, пока буфер не будет доступен снова.
Класс CSocketFile
наследуется от CFile
, но не поддерживает функции-члены класса CFile, такие как функции позиционирования (Seek
, GetLength
, SetLength
и т. д.), функции блокировки (LockRange
, UnlockRange
) или функцию GetPosition
. Объект CSocketFile должен только записывать или считывать последовательности байтов в/из связанного объекта CSocket
. Так как файл не участвует, такие операции, как Seek
и GetPosition
не имеет смысла.
CSocketFile
является производным от CFile
, поэтому обычно он наследует все эти функции-члены. Чтобы предотвратить это, неподдерживаемые CFile
функции-члены переопределяются в CSocketFile
, чтобы выбросить CNotSupportedException.
Объект CSocketFile
вызывает функции-члены объекта CSocket
для отправки или получения данных.
На следующем рисунке показаны связи между этими объектами на обеих сторонах связи.
CArchive, CSocketFile и CSocket
Цель этой очевидной сложности заключается в том, чтобы защитить вас от необходимости управлять деталями сокета самостоятельно. Вы создаете сокет, файл и архив, а затем начинаете отправлять или получать данные, вставляя их в архив или извлекая их из архива. CArchive, CSocketFile и CSocket управляют сведениями за кулисами.
Объект CSocket
на самом деле является двухфакторным объектом: иногда асинхронным (обычным состоянием) и иногда синхронным. В асинхронном режиме сокет может получать асинхронные уведомления от фреймворка. Однако во время операции, такой как получение или отправка данных, сокет становится синхронным. Это означает, что сокет не получит дополнительных асинхронных уведомлений до завершения синхронной операции. Так как он переключает режимы, можно, например, сделать следующее:
void CMySocket::OnReceive(int nErrorCode)
{
if (0 == nErrorCode)
{
CSocketFile file(this);
CArchive ar(&file, CArchive::load);
CString str;
ar >> str;
}
}
Если CSocket
он не реализован как объект с двумя состояниями, то при обработке предыдущего уведомления можно получить дополнительные уведомления для того же типа события. Например, вы можете получить уведомление при обработке OnReceive
OnReceive
. В приведенном выше фрагменте кода извлечение str
из архива может привести к рекурсии. Переключение состояний предотвращает рекурсию, CSocket
предотвращая дополнительные уведомления. Общее правило: никаких уведомлений в уведомлениях.
Замечание
CSocketFile
можно также использовать как файл (ограниченный) без объекта CArchive
. По умолчанию CSocketFile
параметр bArchiveCompatible конструктора имеет значение TRUE. Это указывает, что объект файла предназначен для использования с архивом. Чтобы использовать объект файла без архива, передайте значение FALSE в параметре bArchiveCompatible .
В режиме "архивируемого" CSocketFile
объект обеспечивает более высокую производительность и снижает опасность "взаимоблокировки". Взаимоблокировка возникает, когда отправляющие и получающие сокеты ожидают друг друга или ожидают доступ к общему ресурсу. Эта ситуация может произойти, если объект CArchive
работал с CSocketFile
так, как он работает с объектом CFile
. С помощью CFile
архив может предположить, что если он получает меньше байтов, чем запрошено, то достигнут конец файла. Однако данные основаны на сообщениях в CSocketFile
; буфер может содержать несколько сообщений, поэтому если получено меньше запрошенных байтов, это не означает конец файла. Приложение не блокируется в этом случае, так как оно может использовать CFile
, и оно может продолжать чтение сообщений из буфера до тех пор, пока буфер не будет пуст. Функция CArchive
полезна для мониторинга состояния буфера архива в таком случае.
Дополнительные сведения см. в статье "Сокеты Windows: использование сокетов с архивами"