Browse Source

initial commit

master
elikicker 2 years ago
parent
commit
d987e6c0f0
  1. 26
      crychat/client/Main.java
  2. 37
      crychat/client/log/EventLogger.java
  3. 54
      crychat/client/net/Client.java
  4. 18
      crychat/client/util/CeasarChipher.java
  5. 26
      crychat/server/Main.java
  6. 37
      crychat/server/log/EventLogger.java
  7. 68
      crychat/server/net/ChatClient.java
  8. 61
      crychat/server/net/ChatServer.java
  9. 18
      crychat/server/util/CeasarChipher.java
  10. 35
      crychat/server/util/Queue.java
  11. 67
      crychat/server/util/ServerBuilder.java

26
crychat/client/Main.java

@ -0,0 +1,26 @@
package client;
import client.log.EventLogger;
import client.net.Client;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Main {
public static EventLogger console;
public static void main(String[] args) {
System.out.println("Client!");
console = new EventLogger(System.out);
Client c = new Client("localhost", 5001);
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
while (true) {
try {
c.write(r.readLine().getBytes());
} catch (Throwable e) {
e.printStackTrace();
}
}
}
}

37
crychat/client/log/EventLogger.java

@ -0,0 +1,37 @@
package client.log;
import java.io.PrintStream;
public class EventLogger {
private static final String ANSI_RESET = "\u001B[0m";
private static final String ANSI_RED = "\u001B[31m";
private static final String ANSI_GREEN = "\u001B[32m";
private static final String ANSI_BLUE = "\u001B[34m";
private static final String ANSI_WHITE = "\u001B[37m";
private final PrintStream stream;
public EventLogger(PrintStream stream) {
this.stream = stream;
}
public void println(String msg) {
stream.println(msg);
}
public void error(String msg) {
stream.println(ANSI_WHITE + "[" + ANSI_RED + "-" + ANSI_WHITE + "] " + msg + ANSI_RESET);
}
public void info(String msg) {
stream.println(ANSI_WHITE + "[" + ANSI_BLUE + "*" + ANSI_WHITE + "] " + msg + ANSI_RESET);
}
public void success(String msg) {
stream.println(ANSI_WHITE + "[" + ANSI_GREEN + "+" + ANSI_WHITE + "] " + msg + ANSI_RESET);
}
public void close() {
stream.close();
}
}

54
crychat/client/net/Client.java

@ -0,0 +1,54 @@
package client.net;
import client.Main;
import client.util.CeasarChipher;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
public class Client {
private Socket s;
private DataInputStream inputStream;
private DataOutputStream outputStream;
private Thread t;
public Client(String host, int port) {
try {
s = new Socket(host, port);
inputStream = new DataInputStream(s.getInputStream());
outputStream = new DataOutputStream(s.getOutputStream());
t = new Thread(() -> {
try {
while (true) {
int len = inputStream.readInt();
byte[] buf = new byte[len];
inputStream.readFully(buf, 0, len);
//TEST
System.out.println(new String(CeasarChipher.decrypt(buf)));
}
} catch (IOException e) {
Main.console.error("An error occurred while reading");
e.printStackTrace();
}
});
t.start();
} catch (Throwable e) {
Main.console.error("An error occurred while creating client!");
e.printStackTrace();
}
}
public void write(byte[] buf) {
try {
outputStream.writeInt(buf.length);
outputStream.write(CeasarChipher.encrypt(buf));
} catch (Throwable e) {
server.Main.console.error("An error occurred while writing data!");
e.printStackTrace();
}
}
}

18
crychat/client/util/CeasarChipher.java

@ -0,0 +1,18 @@
package client.util;
public class CeasarChipher {
public static byte[] encrypt(byte[] x) {
for (int i = 0; i < x.length; ++i) {
x[i] = (byte) ((x[i] + 3) % 256);
}
return x;
}
public static byte[] decrypt(byte[] x) {
for (int i = 0; i < x.length; ++i) {
x[i] = (byte) ((x[i] + 253) % 256);
}
return x;
}
}

26
crychat/server/Main.java

@ -0,0 +1,26 @@
package server;
import server.log.EventLogger;
import server.net.ChatServer;
import server.util.ServerBuilder;
public class Main {
public static EventLogger console;
public static void main(String[] args) {
console = new EventLogger(System.out);
ChatServer server = ServerBuilder.buildServerFromConsoleArgs(args);
if (server == null) {
console.info("Didn't initialize ChatServer!");
console.close();
return;
}
//Start the Server
server.start();
//console.close();
}
}

37
crychat/server/log/EventLogger.java

@ -0,0 +1,37 @@
package server.log;
import java.io.PrintStream;
public class EventLogger {
private static final String ANSI_RESET = "\u001B[0m";
private static final String ANSI_RED = "\u001B[31m";
private static final String ANSI_GREEN = "\u001B[32m";
private static final String ANSI_BLUE = "\u001B[34m";
private static final String ANSI_WHITE = "\u001B[37m";
private final PrintStream stream;
public EventLogger(PrintStream stream) {
this.stream = stream;
}
public void println(String msg) {
stream.println(msg);
}
public void error(String msg) {
stream.println(ANSI_WHITE + "[" + ANSI_RED + "-" + ANSI_WHITE + "] " + msg + ANSI_RESET);
}
public void info(String msg) {
stream.println(ANSI_WHITE + "[" + ANSI_BLUE + "*" + ANSI_WHITE + "] " + msg + ANSI_RESET);
}
public void success(String msg) {
stream.println(ANSI_WHITE + "[" + ANSI_GREEN + "+" + ANSI_WHITE + "] " + msg + ANSI_RESET);
}
public void close() {
stream.close();
}
}

68
crychat/server/net/ChatClient.java

@ -0,0 +1,68 @@
package server.net;
import server.Main;
import server.util.CeasarChipher;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
public class ChatClient {
private final int id;
private final Socket s;
private final DataInputStream inputStream;
private final DataOutputStream outputStream;
private final Thread t;
public ChatClient(int id, Socket s, DataInputStream inputStream, DataOutputStream outputStream) {
this.id = id;
this.s = s;
this.inputStream = inputStream;
this.outputStream = outputStream;
t = new Thread(() -> {
try {
while (true) {
int len = inputStream.readInt();
byte[] buf = new byte[len];
inputStream.readFully(buf, 0, len);
//TEST
System.out.println(new String(CeasarChipher.decrypt(buf)));
}
} catch (IOException e) {
Main.console.error("An error occurred while reading from client (" + s.getRemoteSocketAddress().toString() + ") [id: " + id + "]");
e.printStackTrace();
}
});
try {
t.start();
} catch (Throwable e) {
Main.console.error("An error occurred while starting client (" + s.getRemoteSocketAddress().toString() + ") [id: " + id + "]");
e.printStackTrace();
}
}
public void write(byte[] buf) {
try {
outputStream.writeInt(buf.length);
outputStream.write(CeasarChipher.encrypt(buf));
} catch (Throwable e) {
Main.console.error("An error occurred while writing data to client (" + s.getRemoteSocketAddress().toString() + ") [id: " + id + "]");
e.printStackTrace();
}
}
public void disconnect() {
try {
t.stop();
s.close();
inputStream.close();
outputStream.close();
} catch (Throwable e) {
Main.console.error("An error occurred while disconnecting client (" + s.getRemoteSocketAddress().toString() + ") [id: " + id + "]");
e.printStackTrace();
}
}
}

61
crychat/server/net/ChatServer.java

@ -0,0 +1,61 @@
package server.net;
import server.Main;
import server.util.Queue;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class ChatServer {
private final int port;
private volatile int n_users;
private final Thread t;
private ServerSocket server;
private Queue<Integer> id_q;
public ChatServer(int port, int max_users) {
Main.console.info("Initializing server on port: " + port + " with max_users: " + max_users);
this.port = port;
n_users = 0;
t = new Thread(() -> {
try {
while (true) {
if (n_users == max_users) continue;
Socket s = server.accept();
DataInputStream inputStream = new DataInputStream(s.getInputStream());
DataOutputStream outputStream = new DataOutputStream(s.getOutputStream());
ChatClient client = new ChatClient(id_q.deq(), s, inputStream, outputStream);
n_users++;
}
} catch (IOException e) {
Main.console.error("An error occurred while listening for connections!");
e.printStackTrace();
}
});
id_q = new Queue<>(max_users);
for (int i = 0; i < max_users; ++i) id_q.enq(i);
}
public void start() {
try {
server = new ServerSocket(port);
t.start();
} catch (Throwable e) {
Main.console.error("An error occurred while starting the ChatServer!");
e.printStackTrace();
}
}
public void stop() {
try {
t.stop();
} catch (Throwable e) {
Main.console.error("An error occurred while stopping the ChatServer!");
e.printStackTrace();
}
}
}

18
crychat/server/util/CeasarChipher.java

@ -0,0 +1,18 @@
package server.util;
public class CeasarChipher {
public static byte[] encrypt(byte[] x) {
for (int i = 0; i < x.length; ++i) {
x[i] = (byte) ((x[i] + 3) % 256);
}
return x;
}
public static byte[] decrypt(byte[] x) {
for (int i = 0; i < x.length; ++i) {
x[i] = (byte) ((x[i] + 253) % 256);
}
return x;
}
}

35
crychat/server/util/Queue.java

@ -0,0 +1,35 @@
package server.util;
/*
!!! WORK IN PROGRESS !!!
trying to implement a wait-free queue
*/
import java.util.concurrent.atomic.AtomicReferenceArray;
public class Queue<T> {
private volatile int head = 0, tail = 0;
private final int capacity;
private AtomicReferenceArray<T> items;
public Queue(int capacity) {
this.capacity = capacity;
items = new AtomicReferenceArray<>(capacity);
}
public boolean enq(T x) {
if (tail - head == capacity) return false;
items.set((tail + 1) % capacity, x);
tail++;
return true;
}
public T deq() {
if (tail - head == 0) return null;
T x = items.get((head + 1) % capacity);
head++;
return x;
}
}

67
crychat/server/util/ServerBuilder.java

@ -0,0 +1,67 @@
package server.util;
import server.Main;
import server.net.ChatServer;
public class ServerBuilder {
private static final int DEFAULT_PORT = 5000;
private static final int MAX_USERS = 5;
private static final String HELP_MSG = """
-h, -help: prints this help message.
-p, -port: sets the port for the ChatServer
""";
public static ChatServer buildServerFromConsoleArgs(String[] args) {
int port = DEFAULT_PORT;
int max_users = MAX_USERS;
int ptr = 0;
while (ptr < args.length) {
switch (args[ptr]) {
case "-h":
case "-help":
if (ptr != 0 || args.length > 1) {
Main.console.error("You cannot use -h or -help in combination with other commands!");
return null;
}
Main.console.println(HELP_MSG);
return null;
case "-p":
case "-port":
try {
if (++ptr == args.length) {
Main.console.error("Please enter a port-number (0 to 65536)!");
return null;
}
port = Integer.parseInt(args[ptr], 10);
if (port < 0 || port >= 65536) {
Main.console.error("Please enter a valid port-number (0 to 65536)!");
return null;
}
} catch (NumberFormatException e) {
Main.console.error("Please enter a valid port-number (0 to 65536)!");
return null;
}
break;
case "-m":
case "-max_users":
try {
if (++ptr == args.length) {
Main.console.error("Please enter a user count!");
return null;
}
max_users = Integer.parseInt(args[ptr], 10);
} catch (NumberFormatException e) {
Main.console.error("Please enter a valid user count!");
return null;
}
break;
default:
Main.console.error("Couldn't parse argument: '" + args[ptr] + "', please try '-h' or '-help' for help.");
return null;
}
++ptr;
}
return new ChatServer(port, max_users);
}
}
Loading…
Cancel
Save