From b8c67f7a0893591f8d61c85a914239a7293763ed Mon Sep 17 00:00:00 2001 From: WickedJack99 Date: Mon, 1 Apr 2024 17:25:36 +0200 Subject: [PATCH] Threads and interface Terminatable. --- src/main/java/java/src/Input/InputThread.java | 127 ++++++++++++++++++ .../java/src/Receiving/ReceiverThread.java | 70 ++++++++++ src/main/java/java/src/Terminatable.java | 9 ++ 3 files changed, 206 insertions(+) create mode 100644 src/main/java/java/src/Input/InputThread.java create mode 100644 src/main/java/java/src/Receiving/ReceiverThread.java create mode 100644 src/main/java/java/src/Terminatable.java diff --git a/src/main/java/java/src/Input/InputThread.java b/src/main/java/java/src/Input/InputThread.java new file mode 100644 index 0000000..86fac46 --- /dev/null +++ b/src/main/java/java/src/Input/InputThread.java @@ -0,0 +1,127 @@ +/** + * @author Aaron Moser + */ + +package java.src.Input; + +import java.src.Terminatable; +import java.src.Peers.Peer; +import java.src.Peers.PeerOrganizer; +import java.src.Sending.SendingQueue; +import java.src.Sending.Data.PublishFileNameNotification; +import java.util.Scanner; + +public class InputThread extends Thread implements Terminatable { + + private Terminatable receiverThread; + private Terminatable senderThread; + + private SendingQueue sendingQueue; + + private PeerOrganizer peerOrganizer = new PeerOrganizer(); + + private boolean inputThreadRunning = true; + + private boolean receivedValidIP = false; + private boolean receivedValidAndFreePort = false; + + public InputThread(Terminatable senderThread, Terminatable receiverThread, SendingQueue sendingQueue) { + this.senderThread = senderThread; + this.receiverThread = receiverThread; + this.sendingQueue = sendingQueue; + } + + @Override + public void run() { + + String localIpAddress = null; + int localPort = -1; + + Scanner scanner = new Scanner(System.in); + while (!receivedValidIP) { + System.out.println("Enter ip:"); + + localIpAddress = scanner.nextLine(); + + receivedValidIP = NetworkController.hasNetworkInterfaceWithIP(localIpAddress); + } + + while (!receivedValidAndFreePort) { + System.out.println("Enter port:"); + + String localPortAsString = scanner.nextLine(); + + localPort = Integer.valueOf(localPortAsString); + + receivedValidAndFreePort = NetworkController.isPortFree(localPort); + } + + while (inputThreadRunning) { + + System.out.println("This peer is online.\n"); + + System.out.println("Enter command:"); + + String userInput = scanner.nextLine(); + + String[] inputArgs = userInput.split(":"); + + if (inputArgs.length >= 1) { + String command = inputArgs[0]; + + System.out.println(command); + + switch (command) { + case "exit": { + // Terminates sender thread, receiver thread and this thread. + if (senderThread != null) { + senderThread.terminate(); + } + if (receiverThread != null) { + receiverThread.terminate(); + } + this.terminate(); + }break; + case "ShowNodes": { + // TODO send onlineStateRequests to all peers in json file + // Start timeouts for all requests + // Update online states according to received, timeouted messages + }break; + case "ShowFiles": { + // Display own files information of jsons + }break; + case "PublishFile": { + if (inputArgs.length < 2) { + System.err.println("Too few arguments."); + } else if (inputArgs.length > 2) { + System.err.println("Too many arguments."); + } else { + // get list of online peers from json + // for each peer online send publish file name + //sendingQueue.add(new PublishFileNameNotification(peerOrganizer.getLocalPeer(), null, command)); + } + }break; + case "GetFile": { + if (inputArgs.length < 2) { + System.err.println("Too few arguments."); + } else if (inputArgs.length > 2) { + System.err.println("Too many arguments."); + } else { + // check which peer has file + // send get message to that peer + // if own file, just print + } + }break; + default: { + System.out.println("Unknown command."); + }break; + } + } + } + scanner.close(); + } + + public void terminate() { + inputThreadRunning = false; + } +} diff --git a/src/main/java/java/src/Receiving/ReceiverThread.java b/src/main/java/java/src/Receiving/ReceiverThread.java new file mode 100644 index 0000000..7fff8d8 --- /dev/null +++ b/src/main/java/java/src/Receiving/ReceiverThread.java @@ -0,0 +1,70 @@ +/** + * @author Aaron Moser + */ + +package java.src.Receiving; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.src.Terminatable; + +/** + * An instance of a ReceiverThread is handling incoming traffic by putting data into an internal + * ReceivingQueue. Which is then processed by the RequestExecuterThread. + */ +public class ReceiverThread extends Thread implements Terminatable { + private boolean receiverThreadRunning = false; + + private DatagramSocket datagramSocket = null; + private ReceivingQueue receivingQueue = null; + + public ReceiverThread(DatagramSocket datagramSocket, ReceivingQueue receivingQueue) { + this.datagramSocket = datagramSocket; + this.receivingQueue = receivingQueue; + this.receiverThreadRunning = true; + } + + @Override + public void run() { + byte[] receiveBuffer = new byte[65535]; + DatagramPacket datagramPacket = null; + + while (receiverThreadRunning) { + datagramPacket = new DatagramPacket(receiveBuffer, receiveBuffer.length); + try { + datagramSocket.receive(datagramPacket); + if (receiveBuffer != null) { + receivingQueue.add(new ReceivedData(data(receiveBuffer).toString())); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + /** + * Terminates this thread by setting its running boolean variable to false. + */ + public void terminate() { + receiverThreadRunning = false; + } + + /** + * Source: https://www.geeksforgeeks.org/working-udp-datagramsockets-java/ + * @param a the byte array to build a String out of it. + * @return a StringBuilder containing the data to build a String. + */ + public static StringBuilder data(byte[] a) { + if (a == null) { + return null; + } + StringBuilder ret = new StringBuilder(); + int i = 0; + while (a[i] != 0) { + ret.append((char) a[i]); + i++; + } + return ret; + } +} diff --git a/src/main/java/java/src/Terminatable.java b/src/main/java/java/src/Terminatable.java new file mode 100644 index 0000000..06b89e5 --- /dev/null +++ b/src/main/java/java/src/Terminatable.java @@ -0,0 +1,9 @@ +/** + * @author Aaron Moser + */ + +package java.src; + +public interface Terminatable { + public void terminate(); +}