This project implements a distributed system in C that performs vector-based numerical computations across multiple machines. It combines TCP socket programming and ONC RPC to allow clients to request computational services remotely, including:
- Dot product of two vectors
- Average computation for two vectors
- Scaling a vector by a real number
Designed for educational purposes, it demonstrates:
- Remote Procedure Call (RPC) design and implementation
- Inter-process communication over TCP sockets
- Concurrent client handling with forked processes
- Dynamic memory management and structured code organization
The system architecture consists of three main components:
A standalone C program (sock_client.c) that:
- Connects via TCP to the RPC client service
- Provides a CLI menu for selecting operations
- Collects vector data and sends requests over the socket
A C server program (rpc_client.c) that:
- Accepts TCP socket connections from clients
- Acts as a bridge between socket clients and the RPC server
- Unpacks socket data, invokes corresponding RPC procedures, and returns results via the socket
A remote service (rpc_server.c) built using ONC RPC that:
- Implements procedures defined in the
rpc.xfile - Handles actual vector calculations like dot product, averaging, and scaling
- Dot Product
- Accepts two integer vectors of size n
- Computes the scalar (dot) product
- Vector Averages
- Accepts two integer vectors of size n
- Calculates the mean value of each vector independently
- Vector Scaling
- Accepts a vector and a real number scalar
- Returns a new vector scaled by the scalar value
Defined in the RPC specification file (rpc.x):
struct two_vectors {
int n;
int x<>;
int y<>;
};
struct avg_result {
float ex;
float ey;
};
struct scalar_product_args {
int n;
int x<>;
int y<>;
};
struct scale_product_args {
float r;
int n;
int x<>;
};
struct float_array {
float arr<>;
};
The following RPC services are implemented:
int dot_product(scalar_product_args)avg_result calc_averages(two_vectors)float_array scale_vector(scale_product_args)
- The socket client connects to the RPC client server over TCP.
- The user selects an operation (dot product, averages, or scaling) from the CLI menu.
- Data is sent via sockets to the RPC client.
- The RPC client translates socket requests into RPC calls to the remote RPC server.
- The RPC server computes results and returns data back through the RPC client to the original socket client.
- The socket client displays results to the user.
This project uses Makefiles:
- Top-level Makefile:
- Calls
Makefile.rpcto generate RPC stubs - Compiles the socket client
- Calls
- Makefile.rpc:
- Uses
rpcgento generate client/server RPC code - Builds
rpc_clientandrpc_server
- Uses
To build the entire project:
make
- Start the RPC server:
./rpc_server
- Start the RPC client (acts as a socket server):
./rpc_client [rpc_server_ip]
- Run the socket client to connect and send requests:
./sock_client [rpc_client_ip]
Example dot product operation:
1: Dot product 2: Averages 3: r*X 4: Exit Choice: 1 Enter n: 3 Enter vector X: 2 3 4 Enter vector Y: 5 6 7 -------------------- Dot product: 56 --------------------
Example averages operation:
------------------------------------------- Average X: 3.000, Average Y: 6.000 -------------------------------------------
- Combines both socket programming and RPC concepts for inter-process communication
- Implements modular, scalable distributed architecture
- Demonstrates fork-based concurrency handling on the RPC client side
- Implements clean separation between transport (sockets) and computation logic (RPC)