task 5 started.

This commit is contained in:
2025-12-22 00:26:19 +01:00
parent e8f1271f06
commit 01bd4ba693
13 changed files with 293 additions and 14 deletions

View File

@@ -22,4 +22,117 @@
3. And finaly we run the client as such 3. And finaly we run the client as such
```bash ```bash
java -cp "out:lib/*" client.Client java -cp "out:lib/*" client.Client
``` ```
### inspecting packets using wireshark.
***
#### Normal functions
***
I installed wireshark-cli and run
```bash
sudo tshark -i lo -f "tcp port 8080" -z follow,tcp,ascii,0
```
In Client program the interaction looked like this
```
Enter an integer: 4
Enter an integer: 6
The sum is: 10
```
And the output of wireshark was as follows
```xml
POST /RPC2 HTTP/1.1
Content-Type: text/xml
User-Agent: Apache XML RPC 3.0 (Sun HTTP Transport)
Cache-Control: no-cache
Pragma: no-cache
Host: localhost:8080
Accept: */*
Connection: keep-alive
Content-Length: 195
<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>sample.sum</methodName>
<params>
<param>
<value><i4>4</i4></value>
</param>
<param>
<value><i4>6</i4></value>
</param>
</params>
</methodCall>
HTTP/1.1 200 OK
Server: Apache XML-RPC 1.0
Connection: close
Content-Type: text/xml
Content-Length: 129
<?xml version="1.0" encoding="UTF-8"?>
<methodResponse>
<params>
<param>
<value><i4>10</i4></value>
</param>
</params>
</methodResponse>
```
I believe this is the expected result.
***
#### Intentional error
I changed the messge call string to `sample.add` instead of the correct `sample.sum` and run the program. obviously it threw an exception. the http response from wireguard was as follows
```xml
POST /RPC2 HTTP/1.1
Content-Type: text/xml
User-Agent: Apache XML RPC 3.0 (Sun HTTP Transport)
Cache-Control: no-cache
Pragma: no-cache
Host: localhost:8080
Accept: */*
Connection: keep-alive
Content-Length: 196
<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>sample.add</methodName>
<params>
<param>
<value><i4>23</i4></value>
</param>
<param>
<value><i4>4</i4></value>
</param>
</params>
</methodCall>
HTTP/1.1 200 OK
Server: Apache XML-RPC 1.0
Connection: close
Content-Type: text/xml
Content-Length: 265
<?xml version="1.0" encoding="UTF-8"?>
<methodResponse>
<fault>
<value>
<struct>
<member>
<name>faultCode</name>
<value><i4>0</i4></value>
</member>
<member>
<name>faultString</name>
<value>No such handler: sample.add</value>
</member>
</struct>
</value>
</fault>
</methodResponse>
```
Again the expected results. I only tested it in one machine. so time will be done may be another time.

View File

@@ -4,6 +4,7 @@ package client;
import java.util.Vector; import java.util.Vector;
import java.util.Scanner; import java.util.Scanner;
import java.net.URL; import java.net.URL;
import java.net.URI;
/** /**
* Client class for XML-RPC communication * Client class for XML-RPC communication
@@ -33,16 +34,11 @@ public class Client {
// URL can be any valid URL. the default port for XML-RPC is 80 // URL can be any valid URL. the default port for XML-RPC is 80
// but here we use 8080 since 80 may need root privileges // but here we use 8080 since 80 may need root privileges
XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl(); XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
config.setServerURL(URI.create("http://localhost:8080/RPC2").toURL()); // config.setServerURL(new URL("http://localhost:8080/RPC2"));
config.setServerURL(new URI("http://localhost:8080/RPC2").toURL());
XmlRpcClient client = new XmlRpcClient(); XmlRpcClient client = new XmlRpcClient();
client.setConfig(config); client.setConfig(config);
// Logging of XML-RPC messages between server and client
XmlRpcCommonsTransportFactory factory = new XmlRpcCommonsTransportFactory(client);
// enable logging
factory.setEnableLogging(true);
client.setTransportFactory(factory);
while (true) { while (true) {
// create parameters to be sent to server method in a vector // create parameters to be sent to server method in a vector
// and populate it // and populate it
@@ -56,7 +52,7 @@ public class Client {
// make the remote method call // make the remote method call
// the result of the remot call must be an Object // the result of the remot call must be an Object
// and be casted to the appropriate type // and be casted to the appropriate type
Object result = client.execute("sample.sum", params); Object result = client.execute("sample.add", params);
// process the result // process the result
int sum = ((Integer) result).intValue(); int sum = ((Integer) result).intValue();
System.out.println("The sum is: " + sum); System.out.println("The sum is: " + sum);

View File

@@ -14,11 +14,6 @@ import java.net.URL;
import org.apache.xmlrpc.server.PropertyHandlerMapping; import org.apache.xmlrpc.server.PropertyHandlerMapping;
import org.apache.xmlrpc.server.XmlRpcServer; import org.apache.xmlrpc.server.XmlRpcServer;
// logging imports
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Server { public class Server {
private static String TAG = "Server"; private static String TAG = "Server";
@@ -26,6 +21,7 @@ public class Server {
public static void main(String[] args) { public static void main(String[] args) {
try { try {
// start XML-RPC server at port 8080 // start XML-RPC server at port 8080
WebServer server = new WebServer(8080); WebServer server = new WebServer(8080);
XmlRpcServer xmlRpcServer = server.getXmlRpcServer(); XmlRpcServer xmlRpcServer = server.getXmlRpcServer();

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,66 @@
package client;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Scanner;
import common.ClientInterface;
import common.ServerInterface;
public class Client extends UnicastRemoteObject implements ClientInterface {
private String clientId;
private ServerInterface server;
protected Client(String clientId, ServerInterface server) throws RemoteException {
super();
this.clientId = clientId;
this.server = server;
server.registerClient(clientId, this);
}
public void sendMessage(String toId, String message) throws RemoteException {
server.sendMessage(clientId, toId, message);
}
public void blockClient(String blockedId) throws RemoteException {
server.blockClient(clientId, blockedId);
}
@Override
public void receiveMessage(String fromId, String message) throws RemoteException {
System.out.println("[" + fromId + "]: " + message);
}
// entry point
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
// get client ID and server info
System.out.print("Enter your client ID: ");
String clientId = scanner.nextLine();
// get recipient ID
System.out.print("Enter recipient ID: ");
String toId = scanner.nextLine();
Registry registry = LocateRegistry.getRegistry("localhost", 1099);
ServerInterface server = (ServerInterface) registry.lookup("ChatServer");
Client client = new Client(clientId, server);
System.out.print("You can start chatting now. Type your messages below: Type exit to log out\n");
while (true) {
String msg = scanner.nextLine();
if (msg.equalsIgnoreCase("exit")) {
System.out.println("Logging out...");
break;
}
client.sendMessage(toId, msg);
}
} catch (Exception e) {
System.err.println("Client exception: " + e.getMessage());
}
}
}

View File

@@ -0,0 +1,16 @@
package common;
/**
* ClientInterface interface
*
* @author Tinsae Ghilay
*
*/
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface ClientInterface extends Remote {
void receiveMessage(String fromId, String message) throws RemoteException;
}

View File

@@ -0,0 +1,23 @@
package common;
/**
* ClientInterface interface
*
* @author Tinsae Ghilay
*
*/
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.List;
public interface ServerInterface extends Remote {
void registerClient(String clientId, ClientInterface client) throws RemoteException;
void sendMessage(String fromId, String toId, String message) throws RemoteException;
void blockClient(String clientId, String blockedId) throws RemoteException;
List<String> getOfflineMessages(String clientId) throws RemoteException;
}

View File

@@ -0,0 +1,69 @@
package server;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;
import java.util.*;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
// import interfaces
import common.ClientInterface;
import common.ServerInterface;
public class Server extends UnicastRemoteObject implements ServerInterface {
private Map<String, ClientInterface> onlineClients = new HashMap<>();
private Map<String, List<String>> offlineMessages = new HashMap<>();
private Map<String, Set<String>> blockedClients = new HashMap<>();
protected Server() throws RemoteException {
super();
}
@Override
public synchronized void registerClient(String clientId, ClientInterface client) throws RemoteException {
onlineClients.put(clientId, client);
blockedClients.putIfAbsent(clientId, new HashSet<>());
// Send any offline messages
List<String> messages = offlineMessages.getOrDefault(clientId, new ArrayList<>());
for (String msg : messages) {
client.receiveMessage("Offline", msg);
}
offlineMessages.remove(clientId);
}
@Override
public synchronized void sendMessage(String fromId, String toId, String message) throws RemoteException {
// Check if recipient blocked sender
Set<String> blocked = blockedClients.getOrDefault(toId, Collections.emptySet());
if (blocked.contains(fromId))
return;
ClientInterface recipient = onlineClients.get(toId);
if (recipient != null) {
recipient.receiveMessage(fromId, message);
} else {
// Store message for offline delivery
offlineMessages.putIfAbsent(toId, new ArrayList<>());
offlineMessages.get(toId).add(fromId + ": " + message);
}
}
@Override
public synchronized void blockClient(String clientId, String blockedId) throws RemoteException {
blockedClients.putIfAbsent(clientId, new HashSet<>());
blockedClients.get(clientId).add(blockedId);
}
@Override
public synchronized List<String> getOfflineMessages(String clientId) throws RemoteException {
return offlineMessages.getOrDefault(clientId, Collections.emptyList());
}
// entry point
public static void main(String[] args) throws Exception {
Server server = new Server();
Registry registry = LocateRegistry.createRegistry(1099);
registry.rebind("ChatServer", server);
System.out.println("Chat server running...");
}
}