Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TOREVIEW] PROTOCOL written + Code for Client and Server #44

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions specs/jlheig/Code/.idea/workspace.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions specs/jlheig/Code/Client/.idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions specs/jlheig/Code/Client/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions specs/jlheig/Code/Client/.idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions specs/jlheig/Code/Client/.idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions specs/jlheig/Code/Client/Client.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
Binary file not shown.
Binary file not shown.
92 changes: 92 additions & 0 deletions specs/jlheig/Code/Client/src/Client.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Client {
public static void main(String[] args) throws IOException {
Client client = new Client();
Scanner scan = new Scanner(System.in);

if(args.length == 0){
System.out.println("Error, we need 1 argument to serve as the server adress");
return;
}

String server = args[0];
client.connect(server, PORT);
boolean stayConnected = true;
String input;
do{
input = scan.nextLine();

if(input.compareTo(QUIT) == 0){
stayConnected = false;
}

client.writer.println(input);
client.writer.flush();

}while(stayConnected);

client.disconnect();
}

private static String QUIT = "QUIT";
private static int PORT = 3334;

private Logger logger = Logger.getLogger(Client.class.getName());

Socket clientSocket;
PrintWriter writer;
BufferedReader reader;
boolean isConnected = false;

public void connect(String server, int port) throws IOException{
try{
clientSocket = new Socket(server, port);
writer = new PrintWriter(clientSocket.getOutputStream());
reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
isConnected = true;
}
catch (IOException e){
logger.log(Level.SEVERE, "Impossible to connect to the server", e.getMessage());
}

new Thread(new listener()).start();
}

public void disconnect() throws IOException {
try {
if (isConnected) {
logger.log(Level.INFO, "Client wants to quit");
isConnected = false;
writer.close();
reader.close();
clientSocket.close();
}
}
catch (IOException e){
logger.log(Level.SEVERE, "Error while disconnecting", e.getMessage());
}
}

class listener implements Runnable {
public void run(){
String resp;
try{
while((isConnected && (resp = reader.readLine()) != null)){
System.out.println(resp);
}
}
catch (IOException e){
logger.log(Level.SEVERE, "Error while listening", e.getMessage());
isConnected = false;
}
}
}
}
3 changes: 3 additions & 0 deletions specs/jlheig/Code/Server/.idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions specs/jlheig/Code/Server/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions specs/jlheig/Code/Server/.idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions specs/jlheig/Code/Server/.idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions specs/jlheig/Code/Server/Server.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
Binary file not shown.
111 changes: 111 additions & 0 deletions specs/jlheig/Code/Server/src/Server.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import java.io.*;
import java.net.*;

public class Server {
public static void main(String[] args) throws IOException {
Server server = new Server();
while (true){
server.waitForClients();
}
}

private static String HELP = "HELP";
private static String QUIT = "QUIT";
private static int PORT = 3334;

private static String ADD = "ADD";
private static String SUB = "SUB";
private static String MULT = "MULT";
private static String DIV = "DIV";

public void waitForClients() throws IOException {
ServerSocket server = new ServerSocket(PORT);
Socket calculator = server.accept();

SocketAddress address = calculator.getRemoteSocketAddress();

if(address instanceof InetSocketAddress){
InetAddress addressInet = ((InetSocketAddress)address).getAddress();
if(addressInet instanceof Inet4Address){
System.out.println("Listening in IPV4 at : " + addressInet + " Port : " + PORT);
}
else if(addressInet instanceof Inet6Address){
System.out.println("Listening in IPV6 at : " + addressInet + " Port : " + PORT);
}
else{
System.err.println("Wrong IP address");
}
}
else{
System.err.println("Wrong internet protocol socket");
}

PrintWriter writer = new PrintWriter(new OutputStreamWriter(calculator.getOutputStream()));
BufferedReader reader = new BufferedReader(new InputStreamReader(calculator.getInputStream()));

writer.println("Hello, please enter the calculation you want to do : ");
writer.flush();

String input = reader.readLine();
while(input != null){
String[] inputSplitted = input.split(" ");

if(inputSplitted.length == 1){
String command = inputSplitted[0];
if(command.compareTo(HELP) == 0){
writer.println("Supported operations : ADD, SUB, MULT, DIV");
writer.println("All operations require only 2 arguments");
writer.println("If you want to quit use command QUIT");
}
else if(command.compareTo(QUIT) == 0){
writer.println("Closing the connection...");
reader.close();
writer.close();
calculator.close();
server.close();
return;
}
else{
writer.println("Error, unsupported command, please use HELP");
}
}
else if(inputSplitted.length == 3){
String operation = inputSplitted[0];
int n1 = Integer.parseInt(inputSplitted[1]);
int n2 = Integer.parseInt(inputSplitted[2]);

if(operation.compareTo(ADD) == 0){
writer.println("Result : " + (n1 + n2));
}
else if(operation.compareTo(SUB) == 0){
writer.println("Result : " + (n1 - n2));
}
else if(operation.compareTo(MULT) == 0){
writer.println("Result : " + (n1 * n2));
}
else if(operation.compareTo(DIV) == 0){
try {
writer.println("Result : " + (n1 / n2));
}
catch (ArithmeticException e){
writer.println("Error, " + e.getMessage() + " please enter a valid divide operation");
}
}
else{
writer.println("Error, unsupported operation, please use HELP");
}
}
else{
writer.println("Error, wrong number of arguments, please use HELP");
}
writer.flush();
input = reader.readLine();
}

reader.close();
writer.close();
calculator.close();
server.close();

}
}
55 changes: 55 additions & 0 deletions specs/jlheig/PROTOCOL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# RES - Exercise-protocol-Design 2021

Authors : Jean-Luc Blanc

Date : 31.03.2021

------

### What transport protocol do we use?

TCP/IP, most used and popular one. It is also the default one with Java sockets.

### How does the client find the server?

When you start a server, it shows the port its listening to. So the client simply has to connect to that port through the right ip adress.

### Who speaks first?

There are no right or wrongs, but usually clients speak first, this therefor allows the server to decide to accept or not the connection of the client

### What is the sequence of messages exchanged by the client and the server?

1. Server listens to a port
2. Client try connecting to the server
3. Server accepts
4. Server is waiting for a calculation
5. Client sends one
6. Server receives it and compute it
7. Server sends an answer to the client
8. Client receives it
9. Client can either ask a new calculation or simply disconnect

### What happens when a message is received from the other party?

Depends on what message was send :
* if the message sent is an invalid command, we send an error message
* if the message is a valid command then we simply send the answer to the calculation

### What is the syntax of the messages? How do we generate and parse them?

That's an arbitrary choice, I would go for that :
* add n1 n2
* sub n1 n2
* mult n1 n2
* div n1 n2

Most basic operations can be decomposed in this form :
* operation
* number on the left
* number on the right

### Who closes the connection and when?

The client decides when to close the connection