TCP Socket Programming in Unix Using C Programming

🎯 Introduction to TCP Socket Programming in Unix using C Programming

TCP (Transmission Control Protocol) is a widely used transport layer protocol in networking that provides reliable, ordered, and error-checked delivery of data between applications. Socket programming allows communication between processes on different or the same devices over a network using TCP/IP protocols. In this blog post, we will explore how to implement a simple ECHO CLIENT-SERVER communication using TCP sockets in C programming language on a Unix-based system.

🎯 Concept of TCP Socket Programming

Socket Programming is a powerful paradigm for network communication, and TCP sockets offer a reliable, stream-oriented, connection-based communication channel. The TCP server listens for incoming connections, and when a client connects, a new socket is created for that client, allowing data exchange between the client and the server. The TCP client establishes a connection with the server and can send and receive data through the established connection.

🎯 ECHO Server Implementation

Let's start by explaining the server implementation:


#include <netinet/in.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <stdio.h>

#include <arpa/inet.h>

#include <string.h>

#include <fcntl.h>


int main() {

    int sd, cd;

    char buf[100] = "";

    struct sockaddr_in ser;


    // Create the socket

    sd = socket(AF_INET, SOCK_STREAM, 0);

    if (sd < 0) {

        printf("SOCKET NOT CREATED\n");

        return 1;

    }


    // Bind the socket to an IP and Port

    bzero(&ser, sizeof(struct sockaddr_in));

    ser.sin_family = AF_INET;

    ser.sin_port = htons(1012);

    inet_aton("172.16.29.78", &ser.sin_addr);

    int b = bind(sd, (struct sockaddr*)&ser, sizeof(ser));

    printf("BIND VALUE: %d\n", b);


    // Start listening for incoming connections

    listen(sd, 5);


    for (;;) {

        // Accept incoming connection

        cd = accept(sd, NULL, NULL);

        int pid = fork();


        if (pid == 0) {

            // Child process (new connection)

            printf("accept value %d\n", cd);

            read(cd, buf, 100);

            printf("MESSAGE FROM CLIENT: %s\n", buf);

            write(cd, buf, strlen(buf));

            close(cd);

            return 0;

        }

    }


    close(sd);

    return 0;

}

🎯 ECHO Client Implementation

Next, let's explain the client implementation:


#include <netinet/in.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <stdio.h>

#include <arpa/inet.h>

#include <string.h>

#include <fcntl.h>


int main() {

    int sd, cd;

    char buf[100] = "", buf1[100] = "";

    struct sockaddr_in ser;


    // Create the socket

    sd = socket(AF_INET, SOCK_STREAM, 0);

    if (sd < 0) {

        printf("SOCKET NOT CREATED\n");

        return 1;

    }


    // Connect to the server

    bzero(&ser, sizeof(struct sockaddr_in));

    ser.sin_family = AF_INET;

    ser.sin_port = htons(1012);

    inet_aton("172.16.29.78", &ser.sin_addr);

    int c = connect(sd, (struct sockaddr*)&ser, sizeof(ser));

    printf("CONNECT %d\n", c);


    if (c < 0) {

        printf("CONNECTION FAILED\n");

        return 1;

    }


    for (;;) {

        // Read user input and send to the server

        printf("ENTER THE MESSAGE: ");

        scanf("%s", buf);

        write(sd, buf, strlen(buf));


        // Receive the response from the server

        read(sd, buf1, 100);

        printf("RECEIVED FROM SERVER: %s\n", buf1);

    }


    close(sd);

    return 0;

}

🎯 Explanation and Output

The provided C programs are a basic implementation of an echo server-client communication using TCP sockets in Unix. The server listens on IP address "172.16.29.78" and port 1012. The client connects to this IP and port and sends messages to the server.

When you compile and run the server using ./tser, it should print "BIND VALUE: 0", indicating that the socket was successfully bound to the specified IP and port. The server will be ready to accept incoming connections. When a client connects, the server will create a new process to handle the communication with that client.

Then, compile and run the client using ./tcli. It should print "CONNECT 0", indicating that the client successfully connected to the server.

The client will prompt you to "ENTER THE MESSAGE". Type any message, and the client will send it to the server. The server, upon receiving the message, will print "MESSAGE FROM CLIENT: <message>" and then send the same message back to the client. The client will then print "RECEIVED FROM SERVER: <message>".

Sample Output:

Server

cc tserver.c -o tser

./tser

BIND VALUE:0

accept value 4

MESSAGE FROM CLIENT:Hello


Client

cc tclient.c -o tcli

./tcli

CONNET 0

ENTER THE MESSAGE

Hello

🎯 Summary

In this blog post, we explored the concepts of TCP socket programming in Unix using C programming language. We implemented a simple echo client-server communication, where the client sent messages to the server, and the server echoed the same message back to the client. The code demonstrated the basic flow of socket programming, including socket creation, binding, listening, accepting connections, and data exchange.

🎯 Key Points

Remember that this is a basic example, and in real-world applications, error handling, security measures, and other features would be crucial considerations. Additionally, it's essential to understand that fork() for handling multiple connections is not suitable for high-performance servers. In such cases, a more advanced approach, like using threads or asynchronous I/O, would be more appropriate.