How to Create a Simple Client-Server Program Using C Sockets - The Legend of Hanuman

How to Create a Simple Client-Server Program Using C Sockets


Are you looking to dive into network programming and wondering how to create a client-server program using C sockets? This step-by-step guide will walk you through building a simple, TCP-based client-server application in C. Whether you’re a beginner or an experienced programmer, this tutorial is designed to help you understand socket programming and implement a functional client-server system. Let’s get started!

What Are Sockets?

Sockets are the backbone of network communication, enabling programs to send and receive data over the internet or local networks. In this tutorial, we’ll focus on TCP sockets, which provide reliable, connection-oriented communication. Sockets act as endpoints for communication between a client (which initiates a connection) and a server (which listens for incoming connections).

By the end of this guide, you’ll have a working program where the client sends a message to the server, and the server echoes it back. If you’re excited to learn more about sockets beyond this tutorial, consider checking out this comprehensive Udemy course on socket programming in C to deepen your knowledge.

Setting Up Your Development Environment

To follow this tutorial, you’ll need:

  • C Compiler: GCC is recommended (available on Linux, macOS, or Windows via MinGW).
  • Text Editor/IDE: VS Code, Vim, or any editor of your choice.
  • Operating System: This guide focuses on Linux, but the code is portable to Windows and macOS with minor tweaks.
  • Libraries: We’ll use standard C libraries like , , and .

Ensure your system is ready by installing GCC (sudo apt install gcc on Ubuntu or equivalent for your OS). No external dependencies are required beyond the standard C library.

Overview of the Client-Server Program

Our goal is to create a simple TCP client-server program:

  • Server: Listens for connections on a specified port, accepts a client, receives a message, and echoes it back.
  • Client: Connects to the server, sends a message, and displays the server’s response.

The program uses TCP for reliable communication, ensuring data is delivered without errors. Let’s break it down step by step.

Step-by-Step Guide to Writing the Server

Here’s how to create the server program (server.c):

1. Create a Socket

Use the socket() function to create a TCP socket.

c

int server_fd = socket(AF_INET, SOCK_STREAM, 0);

if (server_fd < 0) {

    perror(“Socket creation failed”);

    exit(EXIT_FAILURE);

}

  • AF_INET: Specifies IPv4.
  • SOCK_STREAM: Indicates TCP.

2. Bind the Socket

Bind the socket to an IP address (e.g., 127.0.0.1) and port (e.g., 8080).

c

struct sockaddr_in address;

address.sin_family = AF_INET;

address.sin_addr.s_addr = INADDR_ANY; // Bind to any IP

address.sin_port = htons(8080);       // Port 8080

 

if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) < 0) {

    perror(“Bind failed”);

    exit(EXIT_FAILURE);

}

  • htons(): Converts the port to network byte order.

3. Listen for Connections

Set the socket to listen for incoming connections.

c

if (listen(server_fd, 3) < 0) {

    perror(“Listen failed”);

    exit(EXIT_FAILURE);

}

  • 3: Maximum number of queued connections.

4. Accept a Client

Accept a client connection using accept().

c

int addrlen = sizeof(address);

int new_socket = accept(server_fd, (struct sockaddr*)&address, (socklen_t*)&addrlen);

if (new_socket < 0) {

    perror(“Accept failed”);

    exit(EXIT_FAILURE);

}

5. Receive and Send Data

Read the client’s message and send it back.

c

char buffer[1024] = {0};

int valread = read(new_socket, buffer, 1024);

printf(“Client: %s\n”, buffer);

send(new_socket, buffer, strlen(buffer), 0);

6. Close the Socket

Close the connection.

c

close(new_socket);

close(server_fd);

Here’s the complete server code:

c

#include

#include

#include

#include

#include

#include

 

int main() {

    int server_fd, new_socket;

    struct sockaddr_in address;

    int addrlen = sizeof(address);

    char buffer[1024] = {0};

 

    // Create socket

    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {

        perror(“Socket creation failed”);

        exit(EXIT_FAILURE);

    }

 

    // Set address

    address.sin_family = AF_INET;

    address.sin_addr.s_addr = INADDR_ANY;

    address.sin_port = htons(8080);

 

    // Bind

    if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) < 0) {

        perror(“Bind failed”);

        exit(EXIT_FAILURE);

    }

 

    // Listen

    if (listen(server_fd, 3) < 0) {

        perror(“Listen failed”);

        exit(EXIT_FAILURE);

    }

 

    // Accept

    if ((new_socket = accept(server_fd, (struct sockaddr*)&address, (socklen_t*)&addrlen)) < 0) {

        perror(“Accept failed”);

        exit(EXIT_FAILURE);

    }

 

    // Read and echo

    int valread = read(new_socket, buffer, 1024);

    printf(“Client: %s\n”, buffer);

    send(new_socket, buffer, strlen(buffer), 0);

 

    // Close

    close(new_socket);

    close(server_fd);

    return 0;

}

Step-by-Step Guide to Writing the Client

Now, let’s create the client program (client.c):

1. Create a Socket

Similar to the server, create a TCP socket.

c

int sock = socket(AF_INET, SOCK_STREAM, 0);

if (sock < 0) {

    perror(“Socket creation failed”);

    exit(EXIT_FAILURE);

}

2. Set Up Server Address

Specify the server’s IP and port.

c

struct sockaddr_in serv_addr;

serv_addr.sin_family = AF_INET;

serv_addr.sin_port = htons(8080);

if (inet_pton(AF_INET, “127.0.0.1”, &serv_addr.sin_addr) <= 0) {

    perror(“Invalid address”);

    exit(EXIT_FAILURE);

}

  • inet_pton(): Converts the IP string to binary.

3. Connect to the Server

Establish a connection using connect().

c

if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {

    perror(“Connection failed”);

    exit(EXIT_FAILURE);

}

4. Send Data

Send a message to the server.

c

char *message = “Hello from client”;

send(sock, message, strlen(message), 0);

5. Receive Response

Read the server’s response.

c

char buffer[1024] = {0};

int valread = read(sock, buffer, 1024);

printf(“Server: %s\n”, buffer);

6. Close the Socket

Close the connection.

c

close(sock);

Here’s the complete client code:

c

#include

#include

#include

#include

#include

#include

#include

 

int main() {

    int sock;

    struct sockaddr_in serv_addr;

    char *message = “Hello from client”;

    char buffer[1024] = {0};

 

    // Create socket

    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {

        perror(“Socket creation failed”);

        exit(EXIT_FAILURE);

    }

 

    // Set server address

    serv_addr.sin_family = AF_INET;

    serv_addr.sin_port = htons(8080);

    if (inet_pton(AF_INET, “127.0.0.1”, &serv_addr.sin_addr) <= 0) {

        perror(“Invalid address”);

        exit(EXIT_FAILURE);

    }

 

    // Connect

    if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {

        perror(“Connection failed”);

        exit(EXIT_FAILURE);

    }

 

    // Send message

    send(sock, message, strlen(message), 0);

    printf(“Message sent\n”);

 

    // Receive response

    int valread = read(sock, buffer, 1024);

    printf(“Server: %s\n”, buffer);

 

    // Close

    close(sock);

    return 0;

}

Running the Program

Follow these steps to test your client-server program:

1.Compile the code:

  bash

   gcc server.c -o server

   gcc client.c -o client

2. Start the server:

   bash

   ./server

3. Run the client in a separate terminal:

   bash

   ./client

4. Expected output:

  • Server: Client: Hello from client
  • Client: Message sent and Server: Hello from client

The server will wait for a connection, receive the client’s message, and echo it back. The client will display the server’s response.

Common Issues and Troubleshooting

Socket programming can be tricky. Here are common issues and fixes:

  • Address already in use: The server didn’t close properly. Add setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) before bind().
  • Connection refused: Ensure the server is running and the IP/port match.
  • Partial sends/receives: Use loops to handle incomplete data transfers.
  • Debugging tips: Use perror() for error details and printf() to trace execution.

Enhancing the Program

Want to take your program further? Try these ideas:

  • Multi-client support: Use threads or select() to handle multiple clients.
  • Custom protocol: Build a chat app or file transfer system.
  • Error logging: Save errors to a file for debugging.
  • Command-line arguments: Let users specify IP and port dynamically.

Conclusion

Congratulations! You’ve built a simple client-server program using C sockets. This tutorial covered creating TCP sockets, binding and listening on the server, connecting from the client, and exchanging messages. Socket programming is a powerful skill used in everything from web servers to IoT devices.

Ready to take your skills further? Experiment with UDP sockets, add a graphical interface, or explore network security. For a structured learning path, check out this Udemy course on socket programming in C to master advanced concepts.


Post Views: 194


Share this content:

I am a passionate blogger with extensive experience in web design. As a seasoned YouTube SEO expert, I have helped numerous creators optimize their content for maximum visibility.

Leave a Comment