Реализация отправки файла от клиента серверу при помощи Socket
Помогите пожалуйста разобраться в задании. Изучаю тему Сервер-Клиент, создание подклучения через Socket. Нужно создать Сервер, который может принимать подключение больше одного клиента. После успешного подключения сервер сохраняет информацию о клиенте : имя (client - рандомное число), время, клиентский сокет. После успешного подключения сервер отправляет сообщение клиенту об успешном подключении. Сервер поддерживает набор команд :
- отправка сообщений клиенту;
- exit - отключение клиента от соединения;
- отправка серверу файла - в этот момент указанный файл принимаєтся на стороне сервера и сохраняется у произвольном месте. (с этим пунктом у меня проблема);
Создать Клиента, который должен уметь подключаться (отключиться) к(от) серверу и принимать сообщения от него. Я сделал класс "Клиент" с возможностью многократного запуска. Не пойму как нужно реализовать поцедуру передачи файла серверу . При данной реализации метод передачи файла срабатывает, но на стороне сервера выбрасывает RuntimeException и клиент отключается от сервера. Вот класс Сервер :
public class ServerChat {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
while (true) {
Socket socket = serverSocket.accept();
Random random = new Random();
DataOutputStream dataOut = new DataOutputStream(socket.getOutputStream());
String clientName = "Client-" + random.nextInt(10);
dataOut.writeUTF(clientName + " Connected" + '\n' + "Enter message :");
System.out.println(clientName + " connected ");
saveConnection(clientName, socket);
new Thread(new ClientThread(socket)).start();
}
}
public static void saveConnection (String clientName, Socket socket) throws IOException {
FileOutputStream fos = new FileOutputStream("Connections", true);
String write = clientName + " - Time - " + LocalTime.now() + " - " + socket + '\n';
byte[] bytes = write.getBytes();
fos.write(bytes);
fos.close();
}
}
Класс потока ClientThread :
public class ClientThread implements Runnable{
private final Socket socket;
public ClientThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
DataInputStream dataInput = new DataInputStream(socket.getInputStream());
DataOutputStream dataOut = new DataOutputStream(socket.getOutputStream());
Scanner scanner = new Scanner(System.in);
String path = "C:\\Users\\Артур\\IdeaProjects\\ClientChat\\Client\\src\\main\\java\\Org\\example\\Client\\FileFromClient";
FileTransfer fileTransfer = new FileTransfer(socket);
while (true) {
String message = dataInput.readUTF();
System.out.println("Received message : " + " - " + message);
dataOut.writeUTF(" Received ");
System.out.println("Enter message:");
String mes = scanner.nextLine();
if(mes.equals(path)){
fileTransfer.receive("FileFromClient");
System.out.println("File received !");
continue;
}
else if ("exit".equals(message)) {
break;
}
dataOut.writeUTF(mes);
dataOut.flush();
}
} catch (IOException e) {
throw new RuntimeException(" Client went out from chat ");
} finally {
try {
socket.close();
} catch (IOException ignored) {
}
}
}
}
Класс FileTransfer :
Public class FileTransfer {
private Socket socket;
int bufferSize;
public FileTransfer(Socket client) {
socket = client;
bufferSize = 0;
}
public void receive (String fileName){
try{
InputStream is = socket.getInputStream();
bufferSize = socket.getReceiveBufferSize();
System.out.println("Buffer size = " + bufferSize);
FileOutputStream fos = new FileOutputStream(fileName);
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte[] bytes = new byte[bufferSize];
int count;
while ((count = is.read(bytes)) >= 0){
bos.write(bytes, 0, count);
}
bos.close();
is.close();
} catch (IOException e){
e.printStackTrace();
}
}
public void send (File fileName){
try{
byte[] buffer = new byte[(int) file.length()];
FileInputStream fis = new FileInputStream(fileName);
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
int count;
while ((count = bis.read(buffer)) > 0){
bos.write(buffer, 0, count);
}
bos.close();
fis.close();
bis.close();
} catch (IOException e){
e.printStackTrace();
}
}
}
И класс Клиент с потоком :
public class ClientChat {
public static void main(String[] args) throws IOException {
try (Socket socket = new Socket("localhost", 8080)) {
Scanner scanner = new Scanner(System.in);
DataOutputStream os = new DataOutputStream(socket.getOutputStream());
String path = "C:\\Users\\Артур\\IdeaProjects\\ClientChat\\Client\\src\\main\\java\\Org\\example\\Client\\FileFromClient";
File file = new File(path);
FileTransfer fileTransfer = new FileTransfer(socket);
new Thread(new ServerThread(socket)).start();
while (scanner.hasNext()) {
System.out.println("Enter message:");
String message = scanner.nextLine();
if(message.equals(path)){
fileTtansfer.send(file);
System.out.println("file has been sent");
}
if ("exit".equals(message)) {
break;
}
os.writeUTF(message);
os.flush();
}
}
}
}
public class ServerThread implements Runnable{
private final Socket socket;
public ServerThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try (DataInputStream is = new DataInputStream(socket.getInputStream())) {
while (true) {
String response = is.readUTF();
if ("bye".equals(response)) {
break;
}
System.out.println("Server: " + response);
}
} catch (IOException ignored) {}
}
}