From 2764a232788e6d820ebe95419730a319eea1bd3c Mon Sep 17 00:00:00 2001 From: Julian T Date: Tue, 29 Sep 2020 15:10:59 +0200 Subject: Added java and net assignments --- sem5/oop/m7/.classpath | 6 ++ sem5/oop/m7/.gitignore | 1 + sem5/oop/m7/.project | 17 +++++ sem5/oop/m7/src/InputHandler.java | 30 ++++++++ sem5/oop/m7/src/Main.java | 20 +++++ sem5/oop/m7/src/Message.java | 34 +++++++++ sem5/oop/m7/src/Node.java | 155 ++++++++++++++++++++++++++++++++++++++ sem5/oop/m7/src/PingMessage.java | 46 +++++++++++ sem5/oop/m7/src/TextMessage.java | 14 ++++ 9 files changed, 323 insertions(+) create mode 100644 sem5/oop/m7/.classpath create mode 100644 sem5/oop/m7/.gitignore create mode 100644 sem5/oop/m7/.project create mode 100644 sem5/oop/m7/src/InputHandler.java create mode 100644 sem5/oop/m7/src/Main.java create mode 100644 sem5/oop/m7/src/Message.java create mode 100644 sem5/oop/m7/src/Node.java create mode 100644 sem5/oop/m7/src/PingMessage.java create mode 100644 sem5/oop/m7/src/TextMessage.java (limited to 'sem5/oop') diff --git a/sem5/oop/m7/.classpath b/sem5/oop/m7/.classpath new file mode 100644 index 0000000..fb50116 --- /dev/null +++ b/sem5/oop/m7/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/sem5/oop/m7/.gitignore b/sem5/oop/m7/.gitignore new file mode 100644 index 0000000..ae3c172 --- /dev/null +++ b/sem5/oop/m7/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/sem5/oop/m7/.project b/sem5/oop/m7/.project new file mode 100644 index 0000000..771bfe1 --- /dev/null +++ b/sem5/oop/m7/.project @@ -0,0 +1,17 @@ + + + distchat + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/sem5/oop/m7/src/InputHandler.java b/sem5/oop/m7/src/InputHandler.java new file mode 100644 index 0000000..c6b87d3 --- /dev/null +++ b/sem5/oop/m7/src/InputHandler.java @@ -0,0 +1,30 @@ +import java.io.BufferedReader; +import java.io.InputStreamReader; + +public class InputHandler extends Thread { + private Node node; + + public InputHandler(Node node) { + this.node = node; + } + + public void run() { + BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); + + try { + String line; + while ((line = in.readLine()) != null) { + char cmd = line.charAt(0); + Message msg = null; + if (cmd == '#' || cmd == '!') { + msg = new PingMessage(this.node.name, line.substring(1), cmd == '!'); + } else { + msg = new TextMessage(this.node.name, "", line); + } + this.node.sendMsgLocal(msg); + } + } catch (Exception e){ + System.err.printf("Send err: %s%n", e); + } + } +} diff --git a/sem5/oop/m7/src/Main.java b/sem5/oop/m7/src/Main.java new file mode 100644 index 0000000..d2a1b61 --- /dev/null +++ b/sem5/oop/m7/src/Main.java @@ -0,0 +1,20 @@ +public class Main { + + public static void main(String[] args) { + System.out.println("YEAH LETS GO"); + + try { + Node n = new Node(args[0], args[1]); + InputHandler h = new InputHandler(n); + for (int i = 2; i < args.length; i++) { + n.addNeighbor(args[i]); + } + + h.start(); + n.start(); + } catch (Exception e) { + System.err.printf("Fatal err: %s%n", e); + } + } + +} \ No newline at end of file diff --git a/sem5/oop/m7/src/Message.java b/sem5/oop/m7/src/Message.java new file mode 100644 index 0000000..cad2240 --- /dev/null +++ b/sem5/oop/m7/src/Message.java @@ -0,0 +1,34 @@ +import java.io.OutputStream; +import java.io.ObjectOutputStream; +import java.io.IOException; +import java.io.Serializable; +import java.util.Random; + +public class Message implements Serializable { + public String from; + // If too is empty it is for all + public String to; + public int id; + + public Message(String from, String to) { + this.from = from; + this.to = to; + } + + public void send(OutputStream out) throws IOException{ + ObjectOutputStream objout = null; + try { + objout = new ObjectOutputStream(out); + objout.writeObject(this); + } finally { + if (objout != null) { + objout.close(); + } + } + } + + public void trace(String node) {} + + public void handle(Node n) throws Exception {} +} + diff --git a/sem5/oop/m7/src/Node.java b/sem5/oop/m7/src/Node.java new file mode 100644 index 0000000..2a5d56a --- /dev/null +++ b/sem5/oop/m7/src/Node.java @@ -0,0 +1,155 @@ +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.net.ServerSocket; +import java.net.Socket; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.Semaphore; + +import java.io.OutputStream; +import java.io.ObjectInputStream; +import java.io.InputStream; + +class NodeAddr { + public int port; + public InetAddress addr; + + public NodeAddr(String addr, int port) throws UnknownHostException { + this.port = port; + this.addr = InetAddress.getByName(addr); + } + + public NodeAddr(String fulladdr) throws UnknownHostException { + String fields[] = fulladdr.split(":"); + this.port = Integer.parseInt(fields[1]); + this.addr = InetAddress.getByName(fields[0]); + } +} + +public class Node { + private NodeAddr bind; + private ArrayList neighbors; + + private HashSet seenMsgs; + private Semaphore lock; + + public String name; + + public Node(String bind, String name) throws UnknownHostException { + this.bind = new NodeAddr(bind); + this.neighbors = new ArrayList<>(); + this.name = name; + this.seenMsgs = new HashSet<>(); + this.lock = new Semaphore(1); + } + + public void addNeighbor(String addr) throws UnknownHostException { + this.neighbors.add(new NodeAddr(addr)); + } + + public void start() throws IOException { + ServerSocket socket = null; + try { + socket = new ServerSocket(this.bind.port, 50, this.bind.addr); + + while (true) { + Socket conn = socket.accept(); + Handler h = new Handler(conn, this); + h.start(); + } + } finally { + if (socket != null) { + socket.close(); + } + } + } + + public void sendMsgLocal(Message msg) throws Exception { + // Kind of hacky but thats how we do it + msg.id = ThreadLocalRandom.current().nextInt(); + + if (!this.checkMsg(msg)) { + this.sendMsg(msg); + } + } + + private boolean checkMsg(Message msg) throws InterruptedException { + String msgid = String.format("%s%d", msg.from, msg.id); + this.lock.acquire(); + + if (this.seenMsgs.contains(msgid)) { + this.lock.release(); + return true; + } + this.seenMsgs.add(msgid); + this.lock.release(); + return false; + } + + private void sendMsg(Message msg) throws Exception { + for (NodeAddr n : this.neighbors) { + Socket conn = null; + OutputStream out = null; + try { + conn = new Socket(n.addr, n.port); + out = conn.getOutputStream(); + + msg.send(out); + + } finally { + if (conn != null) { + conn.close(); + } + if (out != null) { + out.close(); + } + } + } + } + + public void handleMsg(Message msg) throws Exception { + if (this.checkMsg(msg)) { + return; + } + if (!msg.to.equals(this.name)) { + msg.trace(this.name); + + // Forward + this.sendMsg(msg); + + if (!msg.to.equals("")) { + return; + } + } + + msg.handle(this); + } +} + +class Handler extends Thread { + private Socket conn; + private Node node; + + public Handler(Socket conn, Node node) { + this.conn = conn; + this.node = node; + } + + public void run() { + InputStream in = null; + ObjectInputStream objin = null; + try { + in = this.conn.getInputStream(); + objin = new ObjectInputStream(in); + Object obj = objin.readObject(); + if (!(obj instanceof Message)) { + throw new Exception("Received object is not a message"); + } + this.node.handleMsg((Message) obj); + } catch (Exception e) { + System.err.printf("Client err: %s%n", e); + } + } +} \ No newline at end of file diff --git a/sem5/oop/m7/src/PingMessage.java b/sem5/oop/m7/src/PingMessage.java new file mode 100644 index 0000000..39a9386 --- /dev/null +++ b/sem5/oop/m7/src/PingMessage.java @@ -0,0 +1,46 @@ +import java.io.Serializable; +import java.util.ArrayList; + +public class PingMessage extends Message implements Serializable { + private boolean is_response; + private boolean do_trace; + public ArrayList trace; + + public PingMessage(String from, String to, boolean trace) { + super(from, to); + this.is_response = false; + this.do_trace = trace; + if (trace) { + this.trace = new ArrayList<>(); + } + } + + public void trace(String node) { + if (!this.do_trace || this.is_response) { + return; + } + System.out.println("DOING TRACE"); + + this.trace.add(node); + } + + public void handle(Node node) throws Exception { + if (this.is_response) { + System.out.printf("%s >> Ping response%n", this.from); + if (this.do_trace) { + System.out.print(" Trace: "); + for (String t : this.trace) { + System.out.printf("%s -> ", t); + } + System.out.print(System.lineSeparator()); + } + return; + } + + this.is_response = true; + this.to = this.from; + this.from = node.name; + + node.sendMsgLocal(this); + } +} diff --git a/sem5/oop/m7/src/TextMessage.java b/sem5/oop/m7/src/TextMessage.java new file mode 100644 index 0000000..f5f5c74 --- /dev/null +++ b/sem5/oop/m7/src/TextMessage.java @@ -0,0 +1,14 @@ +import java.io.Serializable; + +public class TextMessage extends Message implements Serializable { + private String msg; + + public TextMessage(String from, String to, String msg) { + super(from, to); + this.msg = msg; + } + + public void handle(Node node) throws Exception { + System.out.printf("%s >> %s%n", this.from, this.msg); + } +} -- cgit v1.2.3