шпаргалки
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

159 lines
6.0 KiB

2 years ago
/*
* Демонстрационное приложение.
*/
package udp;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.nio.ByteBuffer;
/**
* Класс клиента. Реализует запрос и получение файла от сервера.
*
* @author (C)Y.D.Zakovryashin, 16.01.2023
*/
public class UDPClient {
private DatagramSocket socket;
private DatagramPacket packet;
private byte[] buffer;
private String fileName;
public static void main(String[] args) {
System.out.println("Client started...");
try (DatagramSocket s = new DatagramSocket()) {
UDPClient client = new UDPClient();
client.socket = s;
/**
* Запрос у пользователя имени файла для загрузки.
*/
client.getFileName();
/**
* Запрос файла с сервера.
*/
client.sendFileName();
/**
* Чтение ответа сервера, содержащего либо размер файла, либо код
* ERROR, который означает отсутствие запрошенного файла на сервере.
*/
long size = client.getFileSize();
if (size > UDPServer.ERROR) {
try {
/**
* Загрузка файла с сервера.
*/
client.getFile(size);
System.out.println("File \"" + client.fileName
+ "\" is downloaded successfully.");
} catch (IOException e) {
/**
* Произошла ошибка чтения файла.
*/
System.err.println("File \"" + client.fileName
+ "\" isn\'t downloaded.\n" + e.getMessage());
}
} else {
/**
* Сервер вернул код ERROR, который означает, что на сервере нет
* файла с запрошенным именем.
*/
System.out.println("File \"" + client.fileName + "\" not found");
}
} catch (SocketException ex) {
System.out.println("Error #1: " + ex.getMessage());
} catch (IOException ex) {
System.out.println("Error #2: " + ex.getMessage());
}
System.out.println("Client stoped.");
}
/**
* Чтение имени запрашиваемого файла с консоли.
*
* @return строку с именем файла.
*/
private void getFileName() {
try (BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));) {
/**
* Цикл запроса имени файла должен выполняться до тех пор, пока
* пользователь не введёт непустое имя файла.
*/
do {
System.out.println(">>> Input file name for download:");
fileName = in.readLine();
} while (fileName == null || fileName.trim().isEmpty());
} catch (IOException e) {
System.out.println("Errror: " + e.getMessage());
}
System.out.println("Step 1");
}
/**
* Отправка запроса с именем файла.
*
* @param fileName строка с именем файла.
* @throws IOException в случае общей ошибки ввода/вывода.
*/
private void sendFileName() throws IOException {
buffer = fileName.getBytes();
/**
* В пакет заносится адрес сервера, его порт и сериализованное имя
* файла.
*/
packet = new DatagramPacket(buffer, buffer.length,
InetAddress.getByName(UDPServer.UDP_SERVER_ADDRESS),
UDPServer.UDP_SERVER_PORT);
socket.send(packet);
System.out.println("Step 2");
}
/**
* Получение первого пакета от сервера с размером файла и отправка пакета с
* подтверждением о готовности принять файл.
*
* @return размер файла.
* @throws IOException в случае общей ошибки ввода/вывода.
*/
private long getFileSize() throws IOException {
buffer = new byte[8];
packet = new DatagramPacket(buffer, buffer.length);
/**
* Получение пакета с размером файла.
*/
socket.receive(packet);
long size = ByteBuffer.wrap(packet.getData()).getLong();
if (size > UDPServer.ERROR && size < Integer.MAX_VALUE) {
buffer = UDPServer.OK.getBytes();
} else {
buffer = UDPServer.NO.getBytes();
}
/**
* Подготовка и отправка пакета с подтверждением о готовности принять
* файл.
*/
packet.setData(buffer);
packet.setLength(buffer.length);
socket.send(packet);
System.out.println("Step 3");
return size;
}
private void getFile(long size) throws IOException {
int s = size > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) size;
buffer = new byte[s];
packet.setData(buffer);
socket.receive(packet);
try (FileOutputStream fos = new FileOutputStream("Copy-" + fileName)) {
fos.write(buffer);
}
System.out.println("Step 4");
}
}