Client-server architecture in C++

Client-server architecture is a common pattern in distributed computing, where a server provides services or resources to one or more clients over a network. In C++, you can implement client-server architecture using sockets and the network programming tools provided by the standard library.

Here’s a basic example of a client-server application in C++:

Server side:

c++
#include 
#include 
#include 
#include 
#include 
#include 

int main() {
    int serverSocket = socket(AF_INET, SOCK_STREAM, 0); // create a new socket
    if (serverSocket < 0) {
        std::cerr << "Error creating socket\n";
        exit(1);
    }

    struct sockaddr_in serverAddress;
    std::memset(&serverAddress, 0, sizeof(serverAddress));
    serverAddress.sin_family = AF_INET;
    serverAddress.sin_addr.s_addr = INADDR_ANY;
    serverAddress.sin_port = htons(8080); // listen on port 8080

    if (bind(serverSocket, (struct sockaddr*) &serverAddress, sizeof(serverAddress)) < 0) {
        std::cerr << "Error binding socket\n";
        exit(1);
    }

    if (listen(serverSocket, 5) < 0) { // listen for incoming connections
        std::cerr << "Error listening on socket\n";
        exit(1);
    }

    std::cout <<"Server listening on port 8080...\n";

    int clientSocket;
    struct sockaddr_in clientAddress;
    socklen_t clientAddressSize = sizeof(clientAddress);

    while (true) {
        clientSocket = accept(serverSocket, (struct sockaddr*) &clientAddress, &clientAddressSize); // accept incoming connection
        if (clientSocket < 0) {
            std::cerr << "Error accepting connection\n";
            exit(1);
        }

        char buffer[256];
        int n = read(clientSocket, buffer, 255); // read data from client
        if (n < 0) {
            std::cerr << "Error reading from socket\n";
            exit(1);
        }

        std::cout << "Received message from client: " << buffer << '\n';

        const char* message = "Hello from server!";
        n = write(clientSocket, message, std::strlen(message)); // send response back to client
        if (n < 0) {
            std::cerr << "Error writing to socket\n";
            exit(1);
        }

        close(clientSocket); // close the connection
    }

    close(serverSocket); // close the server socket
    return 0;
}

In this example, we create a new socket using `socket()` and bind it to a port using `bind()`. We then listen for incoming connections using `listen()` and accept incoming connections using `accept()`.Once we have a connection, we read data from the client using `read()` and send a response back using `write()`. Finally, we close the connection using `close()` and continue listening for new connections.

Client side:

c++
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int main() {
    int clientSocket = socket(AF_INET, SOCK_STREAM, 0); // create a new socket
    if (clientSocket < 0) {
        std::cerr << "Error creating socket\n";
        exit(1);
    }

    struct hostent* server = gethostbyname("localhost"); // resolve host name
    if (server == nullptr) {
        std::cerr << "Error resolving hostname\n";
        exit(1);
    }

    struct sockaddr_in serverAddress;
    std::memset(&serverAddress, 0, sizeof(serverAddress));
    serverAddress.sin_family = AF_INET;
    std::memcpy(&serverAddress.sin_addr.s_addr, server->h_addr, server->h_length);
    serverAddress.sin_port = htons(8080); // connect to port 8080

    if (connect(clientSocket, (struct sockaddr*) &serverAddress, sizeof(serverAddress)) < 0) { // connect to server
        std::cerr << "Error connecting to server\n";
        exit(1);
    }

    const char* message = "Hello from client!";
    int n = write(clientSocket, message, std::strlen(message)); // send message to server
    if (n < 0) {
        std::cerr << "Error writing to socket\n";
        exit(1);
    }

    char buffer[256];
    n = read(clientSocket, buffer, 255); // read response from server
    if (n < 0) {
        std::cerr << "Error reading from socket\n";
        exit(1);
    }

    std::cout << "Received message from server: " << buffer << '\n';

    close(clientSocket); // close the connection
    return 0;
}

In this example, we create a new socket using `socket()` and resolve the hostname using `gethostbyname()`. We then connect to the server using `connect()`. Once we're connected, we send a message to the server using `write()` and read the response back using `read()`. Finally, we close the connection using `close()`.

Note that this is just a basic example, and in a real-world application, you would likely need to handle errors, use more robust error handling, and implement additional security measures like authentication and encryption.

Overall, client-server architecture in C++ is a powerful tool for building distributed applications that can scale to handle a large number of clients and provide robust, reliable services overa network.