Сетевое программирование в .NET, страница 16

  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) выберите команду Debug►Start 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 должен выглядеть так.

Peter: Hi, Alex

Alex: Glad to see you!

Peter: I wonder, can I download one of your. . .

Здесь Peter и Alex являются псевдонимами беседующих персон. При выходе из сеанса одного из клиентов сервер должен вывести сообщение: 127.0.0.1.Alex said good-bye. При обмее данными используйте сложные имена (имя или адрес сервера-точка-nick), но в консольные окна выводите только nick.


Классы .NET Framework для управления сетевыми соединениями

Классы .NET Framework значительно упрощают работу с объектами сетевого программирования. Во второй версии Framework появилось несколько новых пространств имен, которые содержат классы, реализующие большую часть функций, необходимых для разработки сетевых приложений и управления сетевыми устройствами. Пространство System.Net содержит 6 пространств: Cache, Configuration, Mail, Mime, NetworkInformation, Sockets.