EvolveDev
Theme toggle is loading

Building a Simple Chat App in C: A Linux Socket Programming Guide for Beginners

Learn to build a simple chat app in C using Linux sockets! This beginner-friendly guide covers client-server communication, multiplexing with poll(), and hands-on coding.

Published: Apr 04, 2025

Building a Simple Chat App in C: A Linux Socket Programming Guide for Beginners

Architecture Diagram

+------------+          +-----------+
|   Client   | <------> |  Server   |
+------------+          +-----------+
     ^                        ^
     | stdin                  | stdin
     v                        v
+----------+            +----------+
|  User    |            |  User    |
| Input    |            | Input    |
+----------+            +----------+

Server Implementation Breakdown

Server Code Structure

#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <poll.h>
#include <unistd.h>
 
int main() {
    // Socket creation and setup
    // Main loop with poll()
    // Communication handling
    return 0;
}

Step-by-Step Explanation

Step 1: Create Socket

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

Step 2: Bind Socket

struct sockaddr_in address = {
    AF_INET,
    htons(9999),
    0
};
bind(sockfd, &address, sizeof(address));

Step 3: Listen for Connections

listen(sockfd, 10);

Step 4: Accept Client Connection

int clientfd = accept(sockfd, 0, 0);

Step 5: Setup poll() Structure

struct pollfd fds[2] = {
    {0, POLLIN, 0},     // stdin
    {clientfd, POLLIN, 0} // client socket
};

Step 6: Main poll() Loop

for (;;) {
    char buffer[256] = {0};
    poll(fds, 2, 50000);
    
    // Handle events...
}

Step 7: Handle Input Events

if (fds[0].revents & POLLIN) {  // stdin input
    read(0, buffer, 255);
    send(clientfd, buffer, 255, 0);
} 
else if (fds[1].revents & POLLIN) {  // client message
    if (recv(clientfd, buffer, 255, 0) == 0) return 0;
    printf("%s\n", buffer);
}

Client Implementation Breakdown

Client Code Structure

#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <poll.h>
#include <unistd.h>
 
int main() {
    // Socket creation and connection
    // Main loop with poll()
    // Communication handling
    return 0;
}

Step-by-Step Explanation

Step 1: Create Socket

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

Step 2: Connect to Server

struct sockaddr_in address = {
    AF_INET,
    htons(9999),
    0
};
connect(sockfd, &address, sizeof(address));

Step 3: Setup poll() Structure

struct pollfd fds[2] = {
    {0, POLLIN, 0},    // stdin
    {sockfd, POLLIN, 0} // server socket
};

Step 4: Main poll() Loop

for (;;) {
    char buffer[256] = {0};
    poll(fds, 2, 50000);
    
    // Handle events...
}

Step 5: Handle Input Events

if (fds[0].revents & POLLIN) {  // stdin input
    read(0, buffer, 255);
    send(sockfd, buffer, 255, 0);
} 
else if (fds[1].revents & POLLIN) {  // server message
    if (recv(sockfd, buffer, 255, 0) == 0) return 0;
    printf("%s\n", buffer);
}

Communication Flow Diagram

Client Process                      Server Process
     |                                   |
     |-------- TCP Connection ---------->|
     |                                   |
     |------- stdin Input -------------->|
     |<----- Received Message -----------|
     |                                   |
     |<----- stdin Input ----------------|
     |------- Received Message --------->|                                      

Key Concepts Explained

poll() System Call

+----------------+
|    poll()      |
+----------------+
|                |       +------------+
|  File Descriptors <----| stdin (0)  |
|                |       | socket fd  |
+----------------+       +------------+
       |
       v
+---------------+
| Event Checking|
| POLLIN        |
| POLLOUT       |
| etc.          |
+---------------+

Network Byte Order

Host Byte Order (e.g., 1234)  ->  htons()  ->  Network Byte Order (e.g., 3412)
Network Byte Order (e.g., 3412) -> ntohs() ->  Host Byte Order (e.g., 1234)

Execution Flow

  1. Start server first:
./server
  1. Start client in another terminal:
./client
  1. Communication test:

Important Notes

  1. Port Number: Both use port 9999 (ensure it's available)
  2. Localhost Only: 0 in address field binds to all interfaces
  3. Buffer Size: Fixed 256-byte buffer (255 chars + null terminator)
  4. Blocking Behavior: poll() with 50s timeout prevents busy-waiting

Limitations and Improvements

  1. Single Client: Server handles only one connection at a time
  2. No Error Handling: Add checks for socket/bind/listen errors
  3. Message Truncation: Messages over 255 bytes will be split
  4. Exit Condition: Closing connection terminates both ends

Full Code with Comments

server.c (Enhanced Comments)

#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <poll.h>
#include <unistd.h>
 
int main() {
    // Create TCP socket
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    
    // Configure server address
    struct sockaddr_in address = {
        AF_INET,          // IPv4
        htons(9999),      // Port
        0                 // Listen on all interfaces
    };
    
    // Bind socket to address
    bind(sockfd, (struct sockaddr*)&address, sizeof(address));
    
    // Start listening
    listen(sockfd, 10);
    
    // Accept incoming connection
    int clientfd = accept(sockfd, 0, 0);
    
    // Configure poll structure
    struct pollfd fds[2] = {
        {0, POLLIN, 0},      // stdin
        {clientfd, POLLIN, 0} // client socket
    };
    
    // Main communication loop
    for (;;) {
        char buffer[256] = {0};
        
        // Wait for events (50s timeout)
        poll(fds, 2, 50000);
        
        // Handle stdin input
        if (fds[0].revents & POLLIN) {
            read(0, buffer, 255);
            send(clientfd, buffer, 255, 0);
        }
        // Handle client message
        else if (fds[1].revents & POLLIN) {
            if (recv(clientfd, buffer, 255, 0) == 0) {
                // Connection closed
                return 0;
            }
            printf("Received: %s\n", buffer);
        }
    }
    
    return 0;
}

client.c (Enhanced Comments)

#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <poll.h>
#include <unistd.h>
 
int main() {
    // Create TCP socket
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    
    // Configure server address
    struct sockaddr_in address = {
        AF_INET,          // IPv4
        htons(9999),      // Port
        0                 // Connect to localhost
    };
    
    // Connect to server
    connect(sockfd, (struct sockaddr*)&address, sizeof(address));
    
    // Configure poll structure
    struct pollfd fds[2] = {
        {0, POLLIN, 0},    // stdin
        {sockfd, POLLIN, 0} // server socket
    };
    
    // Main communication loop
    for (;;) {
        char buffer[256] = {0};
        
        // Wait for events (50s timeout)
        poll(fds, 2, 50000);
        
        // Handle stdin input
        if (fds[0].revents & POLLIN) {
            read(0, buffer, 255);
            send(sockfd, buffer, 255, 0);
        }
        // Handle server message
        else if (fds[1].revents & POLLIN) {
            if (recv(sockfd, buffer, 255, 0) == 0) {
                // Connection closed
                return 0;
            }
            printf("Received: %s\n", buffer);
        }
    }
    
    return 0;
}

References & Further Reading

Essential Socket Programming Resources:

  1. "UNIX Network Programming" by W. Richard Stevens
    The definitive guide to network programming in UNIX environments

  2. "Beej's Guide to Network Programming" (Free Online Resource)
    https://beej.us/guide/bgnet/
    Excellent beginner-friendly tutorial on socket programming

  3. Linux Manual Pages
    Use man 2 socket, man 2 bind, man poll in terminal
    Official Linux system call documentation

  4. "The Linux Programming Interface" by Michael Kerrisk
    Comprehensive guide to Linux system programming

  5. GNU C Library Documentation
    https://www.gnu.org/software/libc/manual/
    Official C standard library documentation

Support & Contact

☕ Support the Developer
If you found this guide helpful, consider supporting my work:
buymeacoffee.com/trish07

🐦 Connect on Twitter/X
For updates and programming tips follow :
Trish & Paul

Learning Path Recommendation

Screenshot 2025-04-04 182657.png
Visual roadmap from basic sockets to advanced network protocols

Path Explanation

  1. Socket Basics: Understand fundamental socket APIs
  2. TCP Client/Server: Master connection-oriented communication
  3. Multiplexing: Learn efficient I/O handling with poll()/select()
  4. Multi-client: Scale to handle concurrent connections
  5. Advanced Protocols: Implement TLS, HTTP, or custom protocols

This visual roadmap helps you:

For any questions or queries, feel free to reach out!


#C#Socket Programming#Networking

Share on:

Copyright © EvolveDev. 2025 All Rights Reserved