Бібліотека прикладів додатків Java

Зміст Робота з класом InetAddress Робота з класом URL Перегляд файлів сервера Web Копіювання файлів сервера Web Контрольна сума аплету Потокові сокети - сервер Потокові сокети - клієнт Спілкування в реальному часі Широкомовник- ні повідомлення Аплет та розширення сервера Web

8.9. Надсилання широкомовних повідомлень

Програма забезпечує можливість надсилання широкомовних (broadcast) повідомлень через мережу TCP/IP. Виконує одночасно роль клієнта та сервера. Приклад демонструє використання класів DatagramSocket та DatagramPacket.

Трохи теорії

Датаграмні сокети не гарантують доставку пакетів даних, але працюють швидше потокових і забезпечують можливість широкомовного розсилання пакетів даних одночасно всім вузлам мережі. Для роботи з такими сокетами програма має створити об'єкт класу DatagramSocket, а також підготувати об'єкт класу DatagramPacket. У нього буде записано блок даних, прийнятий від партнера по мережі.

У класі DatagramSocket є два конструктори, прототипи яких представлені нижче:

Перший із цих конструкторів дозволяє визначити порт для сокету, другий передбачає використання будь-якого вільного порту.

Канал, а також вхідні та вихідні потоки створювати не потрібно. Дані передаються та приймаються методами send та receive, визначеними у класі DatagramSocket:

Після використання сокет слід закрити методом close:

Підготовка об'єкта класу DatagramPacket для прийому пакетів виконується за допомогою наступного конструктора:

Інформація про те, до якого вузол і порт потрібно доставити пакет даних, зберігається над сокеті, а пакеті, тобто у об'єкті класу DatagramPacket.

Опис прикладу

Програма DatagramChat, вихідний текст якої ми розглянемо в цьому розділі, призначена для широкомовної розсилки повідомлень у локальній мережі TCP/IP. Воно одночасно виконує роль клієнта та сервера (рис. 1).

прикладів

Мал. 1. Головне вікно програми DatagramChat

Невдача при відкритті сокету може статися в тому випадку, якщо користувач спробував запустити другу копію програми на одній і тій же робочій станції, де сокет 9997 вже зайнятий. У такому разі програма DatagramChat зможе виконувати роль клієнта, що передає широкомовні повідомлення, але повідомлення від інших робочих станцій не прийматимуться.

Повідомлення буде продубльовано у вікні програми з префіксом ":". Його приймуть усі робочі станції, у тому числі й та, звідки це повідомлення було надіслано. Повідомлення, що приймаються, відзначаються стрілочкою.

Перейдемо до опису вихідного тексту.

Головний клас програми DatagramChat

Метод main, визначений у головному класі програми DatagramChat, створює вікно програми як об'єкт класу FrameWindow:

Це вікно потім відображається методом setVisible.

Клас FrameWindow

Цей клас створено на базі класу Frame:

У ньому ми визначили поля, конструктор та кілька методів.

Наступні два поля призначені для зберігання посилань на кнопки Exit та Save:

Для виключення блокування програми прийом широкомовних повідомлень виконується окремому потоці. Поле sThread зберігає посилання на відповідний клас:

У полях s і dp ми зберігаємо посилання на об'єкти, які застосовуються для надсилання широкомовних повідомлень:

Конструктор класу FrameWindow

Зауважимо, що відразу після ініціалізації кнопка Send блокується конструктором класу FrameWindow:

Після цього конструктор запускає потік прийому повідомлень:

І, нарешті, остання дія – отримання датаграмного сокету для прийому повідомлень:

Метод діяльностівиконує клас FrameWindow

Метод sendString посилає пакет на всі робочі станції мережі із застосуванням датаграмних сокетів.

Метод sendString класу FrameWindow

Вихідний текст методу sendString досить простий:

Переданий рядок спочатку перетворюється на масив байт buf. Зауважимо, що масив записуються символи UNICODE.

Підготовлений пакет передається на сокеті методом send. Сокет s призначений для передачі повідомлень і створюється конструктором класу FrameWindow.

Клас ServerThread

Клас ServerThread створено на базі класу Thread:

У полі frame, визначеному у цьому класі, ми зберігаємо посилання на батьківське вікно:

Поле s використовується для зберігання сокета, на якому виконується прийом широкомовних повідомлень:

Конструктор класу ServerThread

Конструктор просто зберігає посилання на батьківське вікно у відповідному полі:

Метод run класу ServerThread

Цей метод працює в окремому потоці та займається прийомом широкомовних повідомлень.

Відразу після ініціалізації він розблокує кнопку Send і намагається створити серверний сокет:

У процесі створення серверного сокету можливе виникнення виключення SocketException (наприклад, якщо сокет із зазначеним номером вже зайнятий іншою копією нашої програми). Відповідний обробник виводить повідомлення про помилку у вікно програми та зупиняє потік прийому повідомлень.

При вдалому отриманні сокету метод run запускає цикл читання широкомовних повідомлень, що надходять:

Отримані повідомлення відображаютьсяу вікні програми методом консоліPrint.

Метод recvString класу ServerThread

Прийом широкомовних повідомлень виконується методом recvString:

Потім викликається метод receive, який виконує прийом даних.

Прийняті дані перетворюються на рядок UNICODE і повертаються методу, що викликає.