C++ Network Programming: TCP/IP Protocol Stack

C++ Network Programming: TCP/IP Protocol Stack

In modern computer networks, the TCP/IP protocol stack is the cornerstone of Internet communication. It provides a reliable means of communication for applications. In this article, we will delve into the composition of the TCP/IP protocol stack and its basic implementation in C++.

1. Overview of the TCP/IP Protocol Stack

TCP/IP (Transmission Control Protocol/Internet Protocol) is a set of standards used to connect computer networks and facilitate data communication. It is divided into four layers:

  1. Application Layer: Responsible for data transmission of specific applications, such as HTTP, FTP, etc.
  2. Transport Layer: Primarily implements end-to-end data transmission through TCP and UDP.
  3. Network Layer: Responsible for routing and forwarding data, such as IP.
  4. Link Layer: Responsible for data transmission over physical media, such as Ethernet.

2. Basic Socket Programming in C++

To demonstrate how to use C++ for network communication, we will create a simple client-server architecture utilizing the TCP protocol. Our example includes how to create the corresponding Socket and how to handle information exchange.

1. Creating the Server Side

First, we will implement a simple TCP server that can accept messages from clients.

Code Example – <span>server.cpp</span>

#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#define PORT 8080
int main() {    int server_fd, new_socket;    struct sockaddr_in address;    int opt = 1;    int addrlen = sizeof(address);    char buffer[1024] = {0};
    // Create socket    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {        perror("socket failed");        exit(EXIT_FAILURE);    }
    // Force binding to port    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,                   &opt, sizeof(opt))) {        perror("setsockopt");        exit(EXIT_FAILURE);    }
     // Configure address structure     address.sin_family = AF_INET;      address.sin_addr.s_addr = INADDR_ANY;      address.sin_port = htons(PORT); 
     // Bind socket to port     if (bind(server_fd, (struct sockaddr *)&address,              sizeof(address)) < 0) {         perror("bind failed");         exit(EXIT_FAILURE);     }
      // Start listening for client connections      if (listen(server_fd, 3) < 0) {          perror("listen");          exit(EXIT_FAILURE);      }
      std::cout << "Waiting for client connection...\n";
      // Accept new connection      if ((new_socket = accept(server_fd, (struct sockaddr *)&address,                               (socklen_t*)&addrlen))<0) {          perror("accept");          exit(EXIT_FAILURE);      }
      read(new_socket , buffer, 1024);      std::cout << "Received message: " << buffer << "\n";
      const char* hello = "Hello from server";      send(new_socket , hello , strlen(hello) , 0 );
      close(new_socket);      close(server_fd);
       return 0;}

Compiling and Running the Server

Execute the following command in the terminal to compile and run your server:

g++ server.cpp -o server
./server

Effect After Starting:

Once you start this program, the terminal will display the message “Waiting for client connection…”, indicating that the server is ready to accept requests from clients.

2. Creating the Client

Now let’s write a simple TCP client to send messages to the above server and receive responses.

Code Example – <span>client.cpp</span>

#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#define PORT 8080
int main() {   int sock = 0;   struct sockaddr_in serv_addr;   char *hello = "Hello from client";   char buffer[1024] = {0};
   // Create socket file descriptor, return error message if failed.   if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {       std::cout << "\n Socket creation error \n";       return -1;   }
   serv_addr.sin_family = AF_INET;    serv_addr.sin_port = htons(PORT); 
   // Convert IPv4 and IPv6 addresses from text to binary form.   if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0)     {       std::cout << "\nInvalid address/address not supported \n";       return -1;   }

Leave a Comment