Today we are going to see, how we can implement client-server architecture using sockets in C++. I would like to recommend going through all basic concepts related to sockets in part 1 of this tutorial. So, without any further delay; let’s start.
In C++, socket programming is a method of merging or connecting two nodes via a network so that they can communicate without losing any data. One socket (node) listens on a specific port at an IP address, while the other socket establishes a connection with it. While the client connects to the server, the server creates the listener socket
Sample program
- Create an empty project and open it with Project Editor you want. I would like to recommend VS Code.
- Create an empty file server.cpp under the root directory and put the following code inside it.
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h> #include <stdlib.h> #include <netinet/in.h> #include <string.h> using namespace std; //Defining Port
#define PORT 9000
/*
* This method will create server socket, bind and listen to incomming
requests
* Parameters
* @argc: Number of command line args passed
* @*argv[]: Character array containing command line args */
int main(int argc, char const *argv[])
{
int serverFileDescriptor, SOCKET, input; struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
char *msg = "Hello Ninja. Its Server here";
// Creating socket file descriptor
if ((serverFileDescriptor = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("Failed to create socket");
exit(EXIT_FAILURE); }
// No we will attach socket to the port 9000
if (setsockopt(serverFileDescriptor, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
&opt, sizeof(opt)))
{
perror("Failed to set socket options"); exit(EXIT_FAILURE);
}
//Configuring Address
address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons( PORT );
// Forcefully attaching socket to the port 8080
if (bind(serverFileDescriptor, (struct sockaddr *)&address, sizeof(address))<0)
{
perror("Server BINDING Failed"); exit(EXIT_FAILURE);
}
//Now we will listen to incoming requests
if (listen(serverFileDescriptor, 3) < 0) {
perror("Failed when listening...");
exit(EXIT_FAILURE); }
if ((SOCKET = accept(serverFileDescriptor, (struct sockaddr *)&address,
(socklen_t*)&addrlen))<0)
{
perror("Failed to accept incoming request"); exit(EXIT_FAILURE);
}
input = read( SOCKET , buffer, 1024);
cout << buffer<<endl;
cout << "Sending Message to clients...";
send(SOCKET , msg , strlen(msg) , 0 );
return 0;
}
Now, create another file client.cpp and put the following code inside it.
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
using namespace std;
//Defining Port, Note that port is same on which server is listening and on which we want to connect
#define PORT 9000
/*
* This method will create server socket, bind and listen to incomming requests
* Parameters
* @argc: Number of command line args passed
* @*argv[]: Character array containing command line args */
int main(int argc, char const *argv[])
{
int sock = 0, input;
struct sockaddr_in serverAddress; //structure for storing address char *msg = "Hello Server. Its Ninja here";
char buffer[2048] = {0};
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
cout<<("Failed To Create Socket\n");
return -1;
}
//configuring Address
serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(PORT);
// now we will Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, "127.0.0.1", &serverAddress.sin_addr)<=0)
{
cout<<("Invalid address, its not supported"); return -1;
}
if (connect(sock, (struct sockaddr *)&serverAddress, sizeof(serverAddress)) < 0)
{
cout<<("\nConnection with server is Failed \n"); return -1;
}
cout << "Message sent to server from client"; send(sock , msg , strlen(msg) , 0 );
//now we will read message
input = read( sock , buffer, 2048);
//printing Buffer
cout<<("%s\n",buffer );
return 0; }
- Now, Go to the terminal and type
- g++ client.cpp -o client
- g++ Server.cpp -o server
- The output should be.
Uses of Socket Programming
Socket programs allow distinct processes on different systems to communicate with one another. It’s usually used to set up a client-server setup. This post includes an example program as well as the various functions needed to generate the server and client programs. Basic communication protocols like TCP/UDP and raw sockets like ICMP are usually covered by socket programming. When compared to underlying protocols like HTTP/DHCP/SMTP, these protocols offer a low communication overhead.
Some of the basic Data Communication between client and server
- File Transfer: Sends a name and receives a file via file transfer.
- Web Page: Sends a URL and receives a page.
- Echo: Sends a message and receives it back.
Disadvantages
- The C++ can only communicate with the machine that has been requested, not with any other machines on the network.
- Sockets send only raw data. This means that both the client and the server must have data interpretation mechanisms.
we have implemented simple client-server architecture using sockets in C++. I hope you enjoyed the tutorial. You can read more about sockets here
Note: It only runs for Linux machines as some of the libraries we have used for socket programming are only available for Linux.