Сетевое программирование в .NET. Расшифровка IP-адреса (IP address specification). Обеспечение надежности доставки пакетов, страница 16

addr.sin_addr.s_addr = inet_addr (myAddr.c_str());

addr.sin_port = htons (27015);

if (connect (sock, (SOCKADDR*) &addr, sizeof(addr)) == SOCKET_ERROR)

{

cout << "\nFailed to connect";

WSACleanup();

return;

}

else

cout << "\nConnected to : " << addr.sin_addr.s_addr << endl;

char* buf = strcpy (new char[32], "Hallo, Server!");

int nBytes = send (sock, buf, (int)strlen(buf) + 1, 0);

cout << "\nSent: " << buf << "  (" << nBytes << " bytes)";

while (true)

{

nBytes = recv (sock, buf, 32, 0);

if (nBytes <= 0 || nBytes == WSAECONNRESET)

{

cout << "\nConnection Closed\n";

break;

}

cout << "\nReceived: " << buf << "  (" << nBytes << " bytes)\n: ";

cin.getline (buf, 31);

if (strlen(buf) == 0)

break;

nBytes = send (sock, buf, (int)strlen(buf) + 1, 0);

cout << "\nSent: " << buf << "  (" << nBytes << " bytes)";

}

cout << "\n\n";

}

Первая половина клиентского приложения почти совпадает с серверным приложением, далее алгоритм отличается тем, что он не ждет начала сессии, а сам начинает цикл обмена сообщениями. Первое сообщение (приветствие) посылается до входа в цикл обмена. Далее в цикле мы позволяем пользователю ввести произвольную строку текста и отправляем ее на сервер.

Наш сервер упорно отвечает одним и тем же текстом на любое сообщение клиента, кроме строки "Bye". Цикл обмена сообщениями завершается, либо когда сервер закончит сессию (получит строку "Bye"), либо когда пользователь введет пустую строку. Заметьте, что ввод строки, длина которой превышает размер буфера также прервет сессию. Для проверки функционирования связки клиент-сервер (одновременной работы двух приложений):

¨  Сделайте стартовым проект сервера. Для этого выберите в контекстном меню окна Solution Explorer команду Set as StartUp Project,

¨  Запустите серверное приложение (Ctrl+F5),

¨  Переведите фокус в студию, включите (если оно отсутствует) окно Class View,

¨  В контекстном меню клиентского проекта (окна Class View) выберите команду DebugStart new instance. Вы должны увидеть окно клиентского приложения.

¨  Переведите фокус в окно серверного приложения, разместите оба окна так, чтобы было видно, что в них происходит, затем введите в окно клиентского приложения текст сообщения.

¨  Повторяйте последний шаг, пока не убедитесь, что обмен данными с помощью сетевого разъема происходит так, как задумано.

¨  Введите строку "Bye", которая должна завершить сессию.

 

Если вас смущает значение адреса 16777343, выводимое клиентским приложением, то внесите изменение, в котором учтен реальный формат структуры in_addr. Здесь мы заставляем компилятор правильно интерпретировать двоичное содержимое структуры in_addr.

cout << "\nConnected to : "

<< int(addr.sin_addr.S_un.S_un_b.s_b1)<<'.'

<< int(addr.sin_addr.S_un.S_un_b.s_b2)<<'.'

<< int(addr.sin_addr.S_un.S_un_b.s_b3)<<'.'

<< int(addr.sin_addr.S_un.S_un_b.s_b4)<< endl;

Если вы догадались, что это всего-лишь упражнение в программировании и есть гораздо более простой способ вывести то же самое, то (как говорили в наше время) возьмите с полки пирожок. Для того, чтобы убедитьcя, что в каркасе приложения не все так уж просто, замените в клиентском приложении строку: if (nBytes <= 0 ...) на: if (nBytes == 0 ...). Объясните изменения в поведении клиента.

¨  Замените в серверном приложении 1 строкy кода для того, чтобы превратить его в приложение типа Chat (обмен сообщениями между клиентом и сервером).

¨  Исправьте интерфейс так, чтобы диалоги больше походили на Chat. Для этого до входа в цикл обмена сообщениями запросите у пользователей псевдонимы (nicks — от nickname). Chat должен выглядеть так.