0% found this document useful (0 votes)
39 views5 pages

Java RPC Implementation Guide

The document describes an implementation of RPC (Remote Procedure Call) in Java using the Socket and SocketServer libraries. It shows a RPCServer class that runs on port 3000 and handles client requests by performing arithmetic operations. It also shows an RPCClient class that connects to the server, sends operation and number requests, and receives and prints the responses. When run, the server prints the connected clients and received requests, while the client prints the connection, allows sending requests, and prints the responses.

Uploaded by

MboN TeTeW
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
39 views5 pages

Java RPC Implementation Guide

The document describes an implementation of RPC (Remote Procedure Call) in Java using the Socket and SocketServer libraries. It shows a RPCServer class that runs on port 3000 and handles client requests by performing arithmetic operations. It also shows an RPCClient class that connects to the server, sends operation and number requests, and receives and prints the responses. When run, the server prints the connected clients and received requests, while the client prints the connection, allows sending requests, and prints the responses.

Uploaded by

MboN TeTeW
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Implementasi RPC Menggunakan Java

Dua program client ([Link]) dan server ([Link]) di bawah ini memperlihatkan bagaimana
RPC (Remote procedure call) disimplementasikan di dalam Bahasa Pemrogaraman Java menggunakan
pustaka bawaan Socket, SocketServer dan yang terkait.

[Link]:
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

public class RPCServer {

private final ServerSocket serverSocket;

@SuppressWarnings("CallToThreadStartDuringObjectConstruction")
public RPCServer(int port) throws IOException {
serverSocket = new ServerSocket(port);

String localIP = [Link]().getHostAddress();

[Link]("Server is running on " + localIP + ":" + port);

while (true) {

Socket rpcClient = [Link]();


String address = [Link]().toString();

[Link]("New client connected : " + address);

new Thread(() -> {


try {
addHook(rpcClient);
} catch (IOException ex) {
[Link]("Client disconnected " + address);
}
}).start();
}
}

private void addHook(Socket rpcClient) throws IOException {

BufferedReader reader = new BufferedReader(new


InputStreamReader([Link]()));
String line;

while ((line = [Link]()) != null) {

[Link]("Client request : " + line);


String[] commands = [Link](":", 3);
int result;
int operand1 = [Link](commands[1]);
int operand2 = [Link](commands[2]);

String message = "";

switch (commands[0]) {

case "add":
result = (operand1 + operand2);
message = operand1 + " + " + operand2 + " = " + result;
break;

case "sub":
result = (operand1 - operand2);
message = operand1 + " - " + operand2 + " = " + result;
break;

case "mul":
result = (operand1 * operand2);
message = operand1 + " * " + operand2 + " = " + result;
break;

case "div":
result = (operand1 / operand2);
message = operand1 + " / " + operand2 + " = " + result;
break;

case "mod":
result = (operand1 % operand2);
message = operand1 + " % " + operand2 + " = " + result;
break;

PrintStream printStream = new PrintStream([Link](), true);


[Link](message);
}
}

public static void main(String[] args) throws Exception {


RPCServer server = new RPCServer(3000);
}
}

[Link]:
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

public class RPCClient {

private final PrintStream printStream;

@SuppressWarnings("CallToThreadStartDuringObjectConstruction")
public RPCClient(String ipAddress, int port) throws IOException {

Socket rpcClient = new Socket(ipAddress, port);

new Thread(() -> {


try {
BufferedReader reader = new BufferedReader(new
InputStreamReader([Link]()));
String line;

while ((line = [Link]()) != null) {


[Link]("Server response : " + line);
[Link]("\nCommands [add, sub, mul, div, mod, exit] : ");
}
} catch (IOException ex) {
[Link]("\nDisconnected!!");
[Link](0);
}
}).start();

printStream = new PrintStream([Link](), true);

public void sendMessage(String operation) {


Scanner scan = new Scanner([Link]);
[Link]("\nEnter 1st number : ");
int f1 = [Link]();

[Link]("Enter 2nd number : ");


int s1 = [Link]();

[Link](operation + ":" + f1 + ":" + s1);

public static void main(String[] args) {

try {
Scanner scan = new Scanner([Link]);

[Link]("Enter server ip address : ");


String ipAddress = [Link]();

[Link]("Enter connection port : ");


int port = [Link]();

RPCClient client = new RPCClient(ipAddress, port);


[Link]("\nConnected to server\n");

[Link]("Commands [add, sub, mul, div, mod, exit] : ");

while (true) {

scan = new Scanner([Link]);

String command = [Link]();

if ([Link]("exit")) {
[Link](0);
}
[Link](command);

[Link]("\n");

}
} catch (IOException ex) {
[Link]("\nUnable to connected!");
}

Server Output:

Server is running on [Link]:3000


New client connected : /[Link]:52843
Client request : add:10:20
Client request : sub:50:20
Client request : mul:10:2
Client request : div:100:5
Client request : mod:1234:10
Client disconnected /[Link]:52843

Client Output:

Enter server ip address : [Link]


Enter connection port : 3000

Connected to server
Commands [add, sub, mul, div, mod, exit] :
add
Enter 1st number : 10
Enter 2nd number : 20
Server response : 10 + 20 = 30

sub
Enter 1st number : 50
Enter 2nd number : 20
Server response : 50 - 20 = 30

mul
Enter 1st number : 10
Enter 2nd number : 2
Server response : 10 * 2 = 20

div
Enter 1st number : 100
Enter 2nd number : 5
Server response : 100 / 5 = 20
mod
Enter 1st number : 1234
Enter 2nd number : 10
Server response : 1234 % 10 = 4

exit

Common questions

Powered by AI

Without threading, the RPC server would only be capable of handling one client at a time, since the server would need to wait for each connected client to finish its requests before proceeding to accept new connections. This serialized processing would severely degrade performance and responsiveness in a multi-client environment. Threading mitigates this by allowing each client connection to be processed concurrently in separate threads, thus improving the server's throughput and ability to handle multiple simultaneous client requests efficiently .

The RPC server in Java manages concurrent client connections using multithreading, where each client connection is handled by a separate thread. Upon accepting a new client connection through the serverSocket.accept() method, a new Thread is started that runs the addHook method for processing client requests. This design allows the server to handle multiple clients concurrently without blocking the main thread of execution .

The RPC client could improve user interaction and handle incorrect inputs more robustly by implementing detailed input validation and feedback mechanisms. For instance, the client can verify that numerical inputs are indeed numbers using try-catch blocks to handle NumberFormatExceptions. It could also provide clear error messages in case of invalid commands or server connection failures. Additionally, incorporating loop-back prompts for correction after detecting input errors would greatly enhance user experience by preventing crashes due to invalid entries .

The RPC server uses the InetAddress class to retrieve the local host's IP address (via getLocalHost().getHostAddress()), which is then displayed to inform users of the address on which the server is running. This provides a practical advantage in server configuration as it helps administrators quickly identify the server's network address, facilitating setup and connection for clients .

The RPC client uses System.exit(0) for terminating the connection, which forces all program threads to stop immediately. While this effectively shuts down the application, it does not ensure that network resources are released properly. This abrupt method can lead to leftover open sockets or resource locks, impacting system stability or performance over time. A more controlled shutdown process involving the closing of the client socket and streams before exiting would ensure better resource management and prevent potential memory leaks .

In the RPC client, IOException is caught and handled by printing an error message and exiting the program, which helps in maintaining graceful shutdown in case of connection failure. On the server side, IOExceptions are caught within the thread responsible for client communication, allowing the server to log disconnections and continue accepting new clients without crashing. These mechanisms ensure that errors are logged and do not interrupt the entire process, enhancing reliability .

The Java RPC implementation is vulnerable to several security risks, such as unvalidated input leading to code injection or buffer overflow attacks if extended to handle more complex commands. Additionally, the use of plaintext communication over sockets exposes data to interception on unsecured networks. Mitigation strategies include implementing input sanitization to prevent injection attacks, using secure sockets (SSL/TLS) for encrypted communication, and adding authentication mechanisms to restrict unauthorized client connections. Enhancing logging for monitoring and detecting malicious activities would also strengthen security .

The RPC client program performs only basic input validation by checking the first command input but lacks validation for input data types and values, such as ensuring operands are numbers. This minimal validation increases vulnerability to input-related errors, potentially causing runtime exceptions like NumberFormatException when non-numeric input is provided for operands. Improving input validation would significantly enhance program stability by preventing erroneous inputs from causing crashes .

The Java RPC implementation uses BufferedReader for input and PrintStream for output in both client and server, which enhances I/O performance by reducing the number of direct read/write operations to the network socket. BufferedReader efficiently reads chunks of data into memory, decreasing the number of system calls, while PrintStream allows for easy output flushing. These buffering mechanisms improve reliability by minimizing the likelihood of partial data transmission and ensuring complete request-response cycles, which is crucial for maintaining consistent communication in RPC .

The RPC server uses a simple delimiter-based command parsing mechanism, where it splits received strings by colons into commands and operands. This method is efficient for the given use case since the number of commands is limited and their formats are predefined. However, it assumes correct input structure without further validation or error handling for malformed requests, which might reduce robustness in more complex applications. The simplicity of this mechanism allows for quick parsing and processing, enabling fast responses to client requests under controlled conditions .

You might also like