task 5 started.
This commit is contained in:
@@ -23,3 +23,116 @@
|
|||||||
```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.
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -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);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
BIN
week3_TinsaeGhilay/Task 5/out/client/Client.class
Normal file
BIN
week3_TinsaeGhilay/Task 5/out/client/Client.class
Normal file
Binary file not shown.
BIN
week3_TinsaeGhilay/Task 5/out/common/ClientInterface.class
Normal file
BIN
week3_TinsaeGhilay/Task 5/out/common/ClientInterface.class
Normal file
Binary file not shown.
BIN
week3_TinsaeGhilay/Task 5/out/common/ServerInterface.class
Normal file
BIN
week3_TinsaeGhilay/Task 5/out/common/ServerInterface.class
Normal file
Binary file not shown.
BIN
week3_TinsaeGhilay/Task 5/out/server/Server.class
Normal file
BIN
week3_TinsaeGhilay/Task 5/out/server/Server.class
Normal file
Binary file not shown.
66
week3_TinsaeGhilay/Task 5/src/client/Client.java
Normal file
66
week3_TinsaeGhilay/Task 5/src/client/Client.java
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
16
week3_TinsaeGhilay/Task 5/src/common/ClientInterface.java
Normal file
16
week3_TinsaeGhilay/Task 5/src/common/ClientInterface.java
Normal 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;
|
||||||
|
|
||||||
|
}
|
||||||
23
week3_TinsaeGhilay/Task 5/src/common/ServerInterface.java
Normal file
23
week3_TinsaeGhilay/Task 5/src/common/ServerInterface.java
Normal 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;
|
||||||
|
|
||||||
|
}
|
||||||
69
week3_TinsaeGhilay/Task 5/src/server/Server.java
Normal file
69
week3_TinsaeGhilay/Task 5/src/server/Server.java
Normal 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...");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user