Основи мережевого програмування на Java: Мережеві з’єднання через сокети UDP

У наших попередніх двох статтях ми обговорювали, як побудувати простий TCP-клієнт і сервер за допомогою Java. (Читати тут) та як зробити їх багатопотоковими (Читати тут).

У цій останній статті серії про мережеве програмування на Java ми розглянемо, як створити простий, але функціональний UDP-відправник (sender) та приймач (receiver) за допомогою Java. UDP (User Datagram Protocol) — це безз'єднувальний протокол комунікації, що широко використовується в ситуаціях, де критично важлива швидкість, а надійність можна забезпечити на рівні додатка.

pic

Що таке UDP?

UDP розшифровується як User Datagram Protocol і працює поверх IP (Internet Protocol). На відміну від TCP, UDP не встановлює з'єднання перед відправкою даних. Замість цього він надсилає пакети (датаграми) незалежно. Це дозволяє здійснювати швидшу комунікацію, але при цьому відсутні гарантії надійності, порядку доставки та перевірки помилок.

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

Щоб продемонструвати, як працює UDP в Java, ми побудуємо два класи:

  1. UDPSender: виступає в ролі клієнта, який відправляє повідомлення.
  2. UDPReceiver: виступає в ролі сервера, який приймає повідомлення та відповідає на них.

3.1 UDPSender

import java.io.IOException;  
import java.net.*;  
import java.util.Objects;  
import java.util.Scanner;  

public class UDPSender {  
 public UDPSender() throws IOException {  

 // Крок 1: Створення DatagramSocket для відправки та отримання датаграм.  
 DatagramSocket datagramSocket = new DatagramSocket();  
 Scanner keyboard = new Scanner(System.in);  

 while(true){  

 // Крок 2: Запит на введення повідомлення.  
 System.out.println("Введіть ваше повідомлення: ");  
 String message = keyboard.nextLine();  

 // Крок 3: Закриття сокета, якщо користувач введе "quit".  
 if (Objects.equals(message, "quit")){  
 datagramSocket.close();  
 System.out.println("Сокет закрито.");  
 break;  
 }  

 // Крок 4: Перетворення повідомлення в масив байтів.  
 byte[] buffer = message.getBytes();  

 // Крок 5: Створення та відправка DatagramPacket на localhost, порт 2021.  
 DatagramPacket datagramPacket = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("localhost"), 2021);  
 datagramSocket.send(datagramPacket);  

 System.out.println("Відправлено: " + message);  

 // Крок 6: Підготовка до отримання відповіді від сервера.  
 buffer = new byte[1500];  
 datagramPacket = new DatagramPacket(buffer, buffer.length);  
 datagramSocket.receive(datagramPacket);  

 // Крок 7: Перетворення отриманого масиву байтів назад у рядок та відображення.  
 message = new String(buffer).trim();  
 System.out.println("Отримано: " + message);  
 }  
 }  
 public static void main(String[] args) {  
 try {  
 new UDPSender();  
 } catch (Exception e) {  
 e.printStackTrace();  
 }  
 }  
}

Крок 1: Створюється DatagramSocket, щоб мати змогу відправляти та отримувати датаграми.

  • Крок 2: Використовуємо Scanner для отримання вводу користувача.
  • Крок 3: Якщо користувач введе "quit", сокет закривається і цикл завершується.
  • Крок 4: Повідомлення перетворюється в масив байтів.
  • Крок 5: Створюється DatagramPacket з повідомленням, який надсилається серверу на адресу localhost та порт 2021.
  • Крок 6: Підготовлено буфер для отримання відповіді від сервера.
  • Крок 7: Отриманий масив байтів перетворюється в рядок і виводиться на екран.

3.2 UDPReceiver

import java.io.IOException;  
import java.net.DatagramPacket;  
import java.net.DatagramSocket;  
import java.net.InetAddress;  

public class UDPReceiver {  
 public UDPReceiver() throws IOException {  

 // Крок 1: Створення DatagramSocket для прослуховування порту 2021.


DatagramSocket datagramSocket = new DatagramSocket(2021);  
 System.out.println("Приймач працює...");  
 while(true) {  

 // Крок 2: Створення буфера та DatagramPacket для отримання даних.  
 byte[] buffer = new byte[1500];  
 DatagramPacket datagramPacket = new DatagramPacket(buffer, buffer.length);  
 datagramSocket.receive(datagramPacket);  

 // Крок 3: Отримання та виведення отриманого повідомлення.  
 String message = new String(buffer).trim();  
 System.out.println("Отримано повідомлення: " + message);  

 // Крок 4: Отримання адреси та порту відправника.  
 InetAddress senderAddress = datagramPacket.getAddress();  
 int senderPort = datagramPacket.getPort();  

 // Крок 5: Підготовка та відправка повідомлення про підтвердження.  
 message = "Ok.";  
 buffer = message.getBytes();  
 datagramPacket = new DatagramPacket(buffer, buffer.length, senderAddress, senderPort);  
 datagramSocket.send(datagramPacket);  
 System.out.println("Відправлено: " + message);  
 }  
 }  

 public static void main(String[] args) {  
 try {  
 new UDPReceiver();  

 } catch (Exception e) {  
 e.printStackTrace();  
 }  
 }  
}
  • Крок 1: DatagramSocket прослуховує порт 2021 для вхідних пакетів.
  • Крок 2: Створюються буфер та DatagramPacket для отримання даних.
  • Крок 3: Повідомлення витягується з буфера та виводиться.
  • Крок 4: Отримуються IP-адреса та номер порту відправника.
  • Крок 5: Підготовлено та відправлено повідомлення про підтвердження.

Потік роботи

  • Запустіть клас UDPReceiver, щоб почати прослуховувати порт 2021.
  • Запустіть клас UDPSender, який запитує у користувача повідомлення. Відправник перетворює повідомлення в байти та надсилає його як пакет.
  • Приймач витягує та відображає повідомлення.
  • Приймач відправляє підтвердження ("Ok.") назад до відправника.
  • Відправник отримує і відображає підтвердження.
  • Користувач може продовжити відправку повідомлень або ввести "quit" для закриття відправника.

Запуск програми

  • Спочатку запустіть клас UDPReceiver, щоб він був готовий до отримання повідомлень.
  • Запустіть клас UDPSender і вводьте повідомлення для відправки.
  • Введіть будь-яке повідомлення в відправнику, щоб продовжити комунікацію.
  • Введіть "quit" в відправнику, щоб закрити з'єднання.

pic

pic

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

Це кінець серії з трьох частин. Слідкуйте за новими матеріалами!

Перекладено з: Java Networking Basics : Networking with UDP Sockets

Leave a Reply

Your email address will not be published. Required fields are marked *