How to validate logic in sync between server and client sides
A client-server architecture in a computer network is one in which several remote processors (clients) request and receive services from a pre-defined host processor (server).
Server
The server waits for any incoming service requests from clients.
Once a request is received, the server services the client. After dealing with a client, the server closes the connection and returns to the waiting state.
In a multithreaded server, the server creates and dispatches a thread to service a client before returning to the waiting state. This allows a single server to accommodate multiple client requests in parallel.
Client
The client requests a server for services. Upon sending a request for service, the client waits for the server to acknowledge the request, after which service is provided to the client.
Once the client request has been handled, the server terminates the connection.
Sockets
Sockets are key when programming a network.
Sockets are endpoints for sending and receiving data. It is easier to understand if you think of sockets as doors that open into the rooms of both the client and server.
To pass any piece of information between the client and server, we need to know where the respective door is or else, the information will be lost.
Code
Now that we know how both the client and server work, we can write code that encapsulates some logic in sync between them.
Let’s consider an example of how a client-server connection is established while programming. We will be using Java to write a program where the client sends a message to the server. The server receives the message, changes it to uppercase, and sends the updated message back to the client.
Client
import java.net.*;import java.io.*;public class Client {public static void main(String args[]){try{// Create socket with port # of serverSocket s = new Socket("localhost", 2222);// Attaching input streams to socketInputStream str = s.getInputStream();InputStreamReader isr = new InputStreamReader(str);BufferedReader br = new BufferedReader(isr);// Attaching output streams to socketOutputStream out = s.getOutputStream();PrintWriter pw = new PrintWriter(out, true);// Send message to serverpw.println("hello world");// Receive response from serverString server_message = br.readLine();// Print response to screenSystem.out.println("Server says: " + server_message);br.close();pw.close();s.close();}catch(Exception e){System.out.println(e);}}}
Server
import java.net.*;import java.io.*;public class Server {public static void main(String args[]){try{// Creating Server Socket with same port # as in clientServerSocket ss = new ServerSocket(2222);while(true){Socket s = ss.accept(); // Blocked here till request received// Attaching input streams to socketInputStream str = s.getInputStream();InputStreamReader isr = new InputStreamReader(str);BufferedReader br = new BufferedReader(isr);// Attaching output streams to socketOutputStream out = s.getOutputStream();PrintWriter pw = new PrintWriter(out, true);// Receive client messageString client_message = br.readLine();System.out.println("Client says: " + client_message);// Send response to clientString updated_message = client_message.toUpperCase();pw.println(updated_message);br.close();pw.close();s.close();}}catch(Exception e){System.out.println(e);}}}
The following steps briefly describe the code above:
-
Server initiates a
ServerSocketand port number. -
Server invokes
accept()method. This method waits until a client connects to the server. -
While the server waits, the client instantiates a
Socketobject, specifying the server name and port number. -
The constructor of the
Socketattempts to connect the client to the specified server. -
If the connection is successful, the client can communicate with the server.
-
On the server’s side, the
accept()method returns a reference to a new socket that is connected to the client’s socket.
Note: When executing the code, always compile and run the server before the client.
Free Resources