aboutsummaryrefslogtreecommitdiff
path: root/sem5/oop/m7
diff options
context:
space:
mode:
authorJulian T <julian@jtle.dk>2020-09-29 15:10:59 +0200
committerJulian T <julian@jtle.dk>2020-09-29 15:10:59 +0200
commit2764a232788e6d820ebe95419730a319eea1bd3c (patch)
tree7b331f2eb5a7db0fa40e67427117c3c79f1279df /sem5/oop/m7
parentfef26c3cd47c1e6d3a9dc7592db5721b996ead6b (diff)
Added java and net assignments
Diffstat (limited to 'sem5/oop/m7')
-rw-r--r--sem5/oop/m7/.classpath6
-rw-r--r--sem5/oop/m7/.gitignore1
-rw-r--r--sem5/oop/m7/.project17
-rw-r--r--sem5/oop/m7/src/InputHandler.java30
-rw-r--r--sem5/oop/m7/src/Main.java20
-rw-r--r--sem5/oop/m7/src/Message.java34
-rw-r--r--sem5/oop/m7/src/Node.java155
-rw-r--r--sem5/oop/m7/src/PingMessage.java46
-rw-r--r--sem5/oop/m7/src/TextMessage.java14
9 files changed, 323 insertions, 0 deletions
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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>distchat</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
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<NodeAddr> neighbors;
+
+ private HashSet<String> 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<String> 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);
+ }
+}