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.
158 lines
6.0 KiB
158 lines
6.0 KiB
/* |
|
* Демонстрационное приложение. |
|
*/ |
|
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"); |
|
} |
|
}
|
|
|