Сокеты Windows. Пример сокетов с использованием архивов
В этой статье представлен пример использования класса CSocket. В примере используются CArchive
объекты для сериализации данных через сокет. Обратите внимание, что это не сериализация документов в файл или из файла.
В следующем примере показано, как использовать архив для отправки и получения данных через CSocket
объекты. Этот пример разработан таким образом, чтобы два экземпляра приложения (на одном компьютере или на разных компьютерах в сети) обменились данными. Один экземпляр отправляет данные, которые другой экземпляр получает и подтверждает. Любое приложение может инициировать обмен, и либо может выступать в качестве сервера, либо в качестве клиента для другого приложения. Следующая функция определена в классе представления приложения:
void PacketSerialize(long nPackets, CArchive &arData, CArchive &arAck)
{
BYTE bValue = 0;
WORD nCopies = 0;
if (arData.IsStoring())
{
CString strText;
errno_t err;
unsigned int number;
for (int p = 0; p < nPackets; p++)
{
err = rand_s(&number);
// if (err == 0)...
bValue = (BYTE)(number % 256);
err = rand_s(&number);
// if (err == 0)...
nCopies = (WORD)(number % 32000);
// Send header information
arData << bValue << nCopies;
for (int c = 0; c < nCopies; c++)
{
// Send data
arData << bValue;
}
strText.Format(_T("Sender sent packet %d of %d (Value = %d, Copies = %d)"),
p + 1, nPackets, (int)bValue, nCopies);
// Send receipt string
arData << strText;
arData.Flush();
// Receive acknowledgment
arAck >> strText;
// display it
DisplayMessage(strText);
}
}
else
{
CString strText;
BYTE bCheck;
for (int p = 0; p < nPackets; p++)
{
// Receive header information
arData >> bCheck >> nCopies;
for (int c = 0; c < nCopies; c++)
{
// Receive data
arData >> bValue;
if (bCheck != bValue)
{
AfxMessageBox(_T("Packet Failure"));
}
}
// Receive receipt string and display it
arData >> strText;
DisplayMessage(strText);
strText.Format(_T("Recipient received packet %d of %d (Value = %d, Copies = %d)"),
p + 1, nPackets, (int)bValue, nCopies);
// Send acknowledgment
arAck << strText;
arAck.Flush();
}
}
}
Самое важное в этом примере заключается в том, что его структура параллелит ее структуру функции MFC Serialize
. Функция-член PacketSerialize
состоит из инструкции if
с предложением else
. Функция получает две ссылки CArchive в качестве параметров: arData и arAck. Если для хранения (отправки) задан объект архива arData, if
ветвь выполняется; в противном случае, если arData задано для загрузки (получения), функция принимает else
ветвь. Дополнительные сведения о сериализации в MFC см. в разделе "Сериализация".
Примечание.
Предполагается, что объект архива arAck является противоположностью arData. Если arData предназначено для отправки, arAck получает, и наоборот имеет значение true.
Для отправки примеры циклов функций для указанного количества раз каждый раз, при создании некоторых случайных данных для демонстрационных целей. Приложение получит реальные данные из какого-то источника, например файла. Оператор вставки архива arData используется<< для отправки потока из трех последовательных блоков данных:
Заголовок, указывающий характер данных (в этом случае значение переменной bValue и количество копий будет отправлено).
Оба элемента создаются случайным образом для этого примера.
Указанное количество копий данных.
Внутренний
for
цикл отправляет bValue указанное количество раз.Строка с именем strText , отображаемая получателем для своего пользователя.
Для получения функция работает аналогично, за исключением того, что он использует оператор извлечения архива (>>) для получения данных из архива. Принимающее приложение проверяет полученные данные, отображает окончательное сообщение "Получено", а затем отправляет обратно сообщение, которое говорит "Отправлено" для отображения приложения отправки.
В этой модели связи слово "Получено", отправленное в переменной strText , отображается в другом конце связи, поэтому он указывает получателю, что определенное количество пакетов данных было получено. Получатель отвечает с аналогичной строкой, которая говорит "Sent", для отображения на экране исходного отправителя. Получение обеих строк указывает на то, что произошло успешное взаимодействие.
Внимание
Если вы пишете клиентную программу MFC для взаимодействия с установленными (не MFC) серверами, не отправляйте объекты C++ через архив. Если сервер не является приложением MFC, которое понимает типы объектов, которые вы хотите отправить, он не сможет получать и десериализировать объекты. Пример в статье Сокеты Windows: Порядок байтов показывает связь с этим типом.
Дополнительные сведения см. в спецификации сокетов Windows: htonl, htons, ntohl, ntohs. Кроме того, дополнительные сведения см. в следующей статье:
См. также
Сокеты Windows в MFC
CArchive::IsStoring
CArchive::operator <<
CArchive::operator >>
CArchive::Flush
CObject::Serialize