Национална академия по разработка на софтуер



страница8/14
Дата25.07.2016
Размер2.68 Mb.
#6706
1   ...   4   5   6   7   8   9   10   11   ...   14

1.5.UDP сокети


В предходната тема изяснихме как се разработват Java приложения, които си комуникират чрез TCP сокети. В тази тема ще се занимаем със средствата, които платформата Java ни дава за комуникация чрез единични UDP пакети.

Предимствата на протокола UDP


Както знаем, протоколът UDP осигурява изпращане и получаване на единични пакети с данни, пристигането на които не е гарантирано. Поради факта, че не установява надеждна връзка между двете приложения, които комуникират по между си, UDP генерира много по-малък мрежов трафик отколкото TCP и затова по принцип осигурява по-голяма бързина при обмяна на единични съобщения.

Кога да използваме UDP


UDP може да се използва, когато трябва да се изпращат малки по размер и независими едно от друго съобщения. Когато се изпращат обемисти съобщения или ако редът на доставянето на съобщенията е важен, UDP не е подходящ избор.

Протоколът UDP има и още една характерна особеност – той е ненадежден. Успешното изпращане на един UDP пакет не гарантира че той ще пристигне или пък че ако изпратим два UDP пакета един след друг, те ще пристигнат в същия ред, в който са изпратени. Ето защо преди да се вземе решение дали да се използва комуникация по UDP, трябва внимателно да се прецени дали този протокол е подходящ.


Къде се използва UDP в практиката


Типичен пример за използване на UDP протокола е при Интернет услугата DNS. При нея клиентът праща кратка заявка, в която описва за кое име на машина или за кой IP адрес иска информация и каква точно информация (такава заявка се нарича DNS query), а DNS сървърът връща кратък отговор (DNS response) с поисканата информация във вид на единичен UDP пакет.

Забележка: Услугата DNS може да работи и по протокол TCP. Вариантът по TCP е по удобен, ако се прави серия от заявки и се търси гарантираност на отговора, докато за единични заявки е по-удобно и по-бързо да се ползва UDP.

Използване на UDP сокети в Java


В Java за поддръжката на UDP сокети разполагаме с класовете java.net.DatagramSocket и java.net.DatagramPacket. Класът DatagramSocket ни дава възможност да се свързваме (да се bind-ваме) към определен мрежов интерфейс и порт и да изпращаме и получаваме пакети. Класът DatagramPacket реално представлява структура от данни, която описва един UDP пакет.

Пример за UDP сървър


Да илюстрираме използването на посочените класове чрез един пример. Да си поставим за задача изготвянето на приложение, което при поискване връща на потребителя текущата дата. За получаването на клиентски заявки и изпращането на отговор ще използваме единични UDP пакети. Ето едно възможно решение на поставената задача:

UDPDateServer.java

import java.net.*;

import java.util.Date;

public class UDPDateServer {

public static final int LISTENING_UDP_PORT = 12345;

public static final String DATE_REQUEST = "GET DATE";

public static final int RECEIVE_BUFFER_SIZE = 256;

public static void main(String[] args) throws Exception {

// Create UDP socket

DatagramSocket datagramSocket =



new DatagramSocket(LISTENING_UDP_PORT);

System.out.println("UDP Date Server is listening " +



"on port " + LISTENING_UDP_PORT);

while (true) {

// Receive UDP client request

byte[] receiveBuf = new byte[RECEIVE_BUFFER_SIZE];

DatagramPacket packetIn = new

DatagramPacket(receiveBuf, receiveBuf.length);

datagramSocket.receive(packetIn);

String request =

new String(receiveBuf, 0, packetIn.getLength());

// Send response to the client

if (request.equalsIgnoreCase(DATE_REQUEST)) {

String response = new Date().toString();



byte[] responseBuf = response.getBytes();

InetAddress senderIP = packetIn.getAddress();



int senderPort = packetIn.getPort();

DatagramPacket packetOut = new DatagramPacket(

responseBuf, responseBuf.length,

senderIP, senderPort);

datagramSocket.send(packetOut);

}

}



}

}


Както се вижда от кода, сървърът отваря един UDP сокет на порт 12345, който се използва както за получаване, така и за изпращане на UDP пакети. След това в безкраен цикъл получава UDP пакет с клиентска заявка (като счита че тя не надвишава 256 байта), извлича от получения пакет IP адреса и порта на изпращача, проверява дали заявката е за извличане на текущата дата, след което създава пакет с отговор (символен низ, съдържащ текущата дата и час) и го изпраща на клиента. Сървърът приема, че клиентът очаква отговора на същия UDP порт, от който е изпратил заявката си. Единствената валидна заявка, на която сървърът отговаря, е за извличане на текущата дата и час. Тази заявка се разпознава по съдържанието на получения UDP пакет, което трябва да е текста „GET DATE”.

Пример за UDP клиент


Нека сега се опитаме да напишем клиент за нашия сървър. Той трябва да изпрати на сървъра UDP пакет, съдържащ заявка за връщане на текущата дата и да слуша известно време за UDP пакет-отговор от сървъра на същия порт, от който е изпратена заявката. Получаването на отговор от сървъра, разбира се, не е гарантирано и затова чакането му трябва да продължи не повече от някакъв предварително зададен времеви лимит (timeout). Ето и примерна реализация:

UDPDateClient.java

import java.net.*;

public class UDPDateClient {

public static final String DATE_SERVER = "localhost";

public static final int DATE_PORT = 12345;

public static final String DATE_REQUEST = "GET DATE";

public static final int TIMEOUT_IN_SECONDS = 5;

public static void main(String[] args) throws Exception {

// Send request to the UDP Date Server

DatagramSocket datagramSocket = new DatagramSocket();

String request = DATE_REQUEST;

byte[] requestBuf = request.getBytes();

DatagramPacket packetOut = new DatagramPacket(

requestBuf, requestBuf.length,

InetAddress.getByName(DATE_SERVER), DATE_PORT);

datagramSocket.send(packetOut);

System.out.println("Sent date request to the server.");



// Receive the server response

byte[] responseBuf = new byte[256];

DatagramPacket packetIn =



new DatagramPacket(responseBuf, responseBuf.length);

datagramSocket.setSoTimeout(TIMEOUT_IN_SECONDS * 1000);



try {

datagramSocket.receive(packetIn);

String response = new String(

responseBuf, 0, packetIn.getLength());

System.out.println("Server response: " + response);

} catch (SocketTimeoutException ste) {

System.err.println("Timeout! No response received" +

" in " + TIMEOUT_IN_SECONDS + " seconds.");

}

datagramSocket.close();



}

}


Както се вижда от кода, няма нищо сложно. Първо се създава UDP сокет, след това се изпраща UDP пакет със заявка към сървъра и след това се прави опит в рамките на 5 секунди да се получи отговор. Ако се поучи отговор, той се отпечатва, а иначе се отпечатва съобщение за грешка. Грешката означава, че или сървърът не е получил пакета, или го е получил и е пратил отговор, но отговорът се е изгубил. При протокола UDP изгубването на пакет съвсем не е изключено.

Каталог: books -> inetjava
books -> В обятията на шамбала
books -> Книга се посвещава с благодарност на децата ми. Майка ми и жена ми ме научиха да бъда мъж
books -> Николай Слатински “Надеждата като лабиринт” София, Издателство “виденов & син”, 1993 год
books -> София, Издателство “Българска книжница”, 2004 год. Рецензенти доц д. ик н. Димитър Йончев, проф д-р Нина Дюлгерова Научен редактор проф д-р Петър Иванов
books -> Николай Слатински “Измерения на сигурността” София, Издателство “Парадигма”, 2000 год
books -> Книга 2 щастие и успех предисловие
books -> Превръщане на числа от една бройна система в друга
books -> Тантриското преобразяване


Сподели с приятели:
1   ...   4   5   6   7   8   9   10   11   ...   14




©obuch.info 2024
отнасят до администрацията

    Начална страница