# Build your own Redis

*The provided code is a basic TCP server implemented in C.*

```c
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

int main() {
    // Disable output buffering
    setbuf(stdout, NULL);
    setbuf(stderr, NULL);

    // Debugging message
    printf("Logs from your program will appear here!\n");

    int server_fd, client_addr_len;
    struct sockaddr_in client_addr;

    // Step 1: Create a socket
    server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd == -1) {
        printf("Socket creation failed: %s...\n", strerror(errno));
        return 1;
    }

    // Step 2: Set socket options
    int reuse = 1;
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) {
        printf("SO_REUSEADDR failed: %s \n", strerror(errno));
        return 1;
    }

    // Step 3: Define server address
    struct sockaddr_in serv_addr = {
        .sin_family = AF_INET,
        .sin_port = htons(6379),
        .sin_addr = { htonl(INADDR_ANY) },
    };

    // Step 4: Bind the socket
    if (bind(server_fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) != 0) {
        printf("Bind failed: %s \n", strerror(errno));
        return 1;
    }

    // Step 5: Listen for connections
    int connection_backlog = 5;
    if (listen(server_fd, connection_backlog) != 0) {
        printf("Listen failed: %s \n", strerror(errno));
        return 1;
    }

    // Step 6: Accept a client connection
    printf("Waiting for a client to connect...\n");
    client_addr_len = sizeof(client_addr);
    accept(server_fd, (struct sockaddr *) &client_addr, &client_addr_len);
    printf("Client connected\n");

    // Step 7: Close the server socket
    close(server_fd);
    return 0;
}
```

### <mark style="color:yellow;">Let's break down each part to understand its functionality, especially for someone new to socket programming.</mark>

1. **Header files**&#x20;

```c
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
```

* `#include <stdio.h>`: Provides functions for input and output operations, such as `printf` for displaying text.
* `#include <stdlib.h>`: Offers general utilities, including memory allocation (`malloc`, `free`) and process control (`exit`).
* `#include <sys/socket.h>`: Contains definitions for socket functions and structures, like `socket`, `bind`, and `accept`.
* `#include <netinet/in.h>`: Defines structures for internet operations, such as `sockaddr_in`, which is used for handling IP addresses.
* `#include <netinet/ip.h>`: Provides declarations for the IP header structure.
* `#include <string.h>`: Offers functions for manipulating C strings and memory, like `memset` and `strerror`.
* `#include <errno.h>`: Defines macros for reporting and retrieving error conditions through the `errno` variable.
* `#include <unistd.h>`: Declares standard symbolic constants and types, and declares miscellaneous functions, such as `close` for closing file descriptors.

**2. Main Function:**

```c
int main() {
    // Disable output buffering
    setbuf(stdout, NULL);
    setbuf(stderr, NULL);
```

* `int main() {`: The entry point of the program.
* `setbuf(stdout, NULL);` and `setbuf(stderr, NULL);`: These functions disable buffering for standard output (`stdout`) and standard error (`stderr`). This means that any output to the console is displayed immediately, which is helpful for debugging purposes.

**3. Debugging Message:**

```c
printf("Logs from your program will appear here!\n");
```

* `printf`: Outputs the specified string to the console. This line informs the user that the program has started and is ready to log messages.

**4. Variable Declarations:**

```c
int server_fd, client_addr_len;
    struct sockaddr_in client_addr;
```

* `int server_fd, client_addr_len;`: Declares two integer variables. `server_fd` will store the file descriptor for the server socket, and `client_addr_len` will hold the size of the client's address structure.
* `struct sockaddr_in client_addr;`: Declares a structure to store the client's address information. `sockaddr_in` is specifically designed for handling internet addresses.

**5. Socket Creation:**

```c
server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd == -1) {
        printf("Socket creation failed: %s...\n", strerror(errno));
        return 1;
    }
```

* `server_fd = socket(AF_INET, SOCK_STREAM, 0);`: Creates a new socket.
  * `AF_INET`: Specifies the address family for IPv4.
  * `SOCK_STREAM`: Indicates that the socket type is stream-oriented, which is used for TCP connections.
  * `0`: Specifies the protocol. Setting it to `0` lets the system choose the appropriate protocol based on the socket type and address family.
* `if (server_fd == -1) { ... }`: Checks if the socket creation failed. If `socket` returns `-1`, an error occurred.
  * `strerror(errno)`: Converts the error number (`errno`) into a human-readable string describing the error.
  * `return 1;`: Exits the program with a status code of `1`, indicating an error.

**6. Set Socket Options:**

```c
int reuse = 1;
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) {
        printf("SO_REUSEADDR failed: %s \n", strerror(errno));
        return 1;
    }
```

* `int reuse = 1;`: Initializes an integer variable `reuse` to `1`.
* `setsockopt`: Sets options on the socket.
  * `server_fd`: The socket file descriptor.
  * `SOL_SOCKET`: Specifies that the option is at the socket level.
  * `SO_REUSEADDR`: Allows the socket to bind to an address that is in a `TIME_WAIT` state, without waiting for its natural timeout to expire. This is useful for server applications that need to restart and bind to the same port.
  * `&reuse`: A pointer to the value of the option.
  * `sizeof(reuse)`: The size of the option value.
* `if (setsockopt(...) < 0) { ... }`: Checks if setting the socket option failed. If `setsockopt` returns `-1`, an error occurred.

**7. Define Server Address:**

```c
struct sockaddr_in serv_addr = {
        .sin_family = AF_INET,
        .sin_port = htons(6379),
        .sin_addr = { htonl(INADDR_ANY) },
    };
```

* `struct sockaddr_in serv_addr = { ... };`: Initializes a `sockaddr_in` structure to specify the server's address.
  * `.sin_family = AF_INET`: Sets the address family to IPv4.
  * `.sin_port = htons(6379)`: Sets the port number to `6379`. `htons` (host to network short) converts the port number from host byte order to network byte order, ensuring compatibility across different systems.
  * `.sin_addr = { htonl(INADDR_ANY) }`: Sets the IP address to accept connections from any interface. `htonl` (host to network long) converts the address to network byte order. `INADDR_ANY` is a constant that allows the server to accept connections on any of the host

{% hint style="info" %}
***Workflow Steps:***

* **Include Necessary Headers:** Imports standard libraries required for socket programming.
* **Disable Output Buffering:** Ensures immediate output display, useful for debugging.
* **Print Debugging Message:** Indicates the program's start.
* **Declare Variables:** Defines variables for the server socket file descriptor, client address length, and client address structure.
* **Create a Socket:** Initializes a TCP socket using IPv4.
* **Set Socket Options:** Allows the server to reuse the address if restarted, preventing "Address already in use" errors.
* **Define Server Address:** Specifies the server's address family, port number, and IP address.
* **Bind the Socket:** Associates the socket with the specified address and port.
* **Listen for Connections:** Puts the server in a passive mode, waiting for client connection requests.
* **Accept a Client Connection:** Waits for an incoming client connection and acknowledges it.
* **Close the Server Socket:** Closes the server socket, releasing the associated resources.
  {% endhint %}

{% hint style="info" %}
***Understanding and Learning:***

To comprehend this code, focus on the following areas:

* **Socket Programming Basics:** Understand the purpose of sockets in network communication and the differences between TCP and UDP protocols.
* **Client-Server Model:** Learn how servers and clients interact, including the roles of binding, listening, and accepting connections on the server side, and connecting on the client side.
* **System Calls and Functions:** Familiarize yourself with system calls like `socket`, `bind`, `listen`, `accept`, and `setsockopt`, including their parameters and return values.
* **Error Handling:** Recognize the importance of checking return values for system calls and handling errors appropriately using `errno` and `strerror`.
  {% endhint %}

{% hint style="info" %}
***Additional Resources:***

To deepen your understanding of socket programming in C, consider exploring the following resources:

1. **Beej's Guide to Network Programming**: A comprehensive guide covering various aspects of network programming in C.

   [Beej](https://beej.us/guide/bgnet/)
2. **Socket Programming in C/C++ - javatpoint**: An introductory tutorial on socket programming in C and C++.

   [Javatpoint](https://www.javatpoint.com/socket-programming-in-c-or-cpp)
3. **Socket Programming in C - GeeksforGeeks**: A detailed article explaining socket programming concepts with examples.

   [GeeksforGeeks](https://www.geeksforgeeks.org/socket-programming-cc/)
4. **A Beginner's Guide to Socket Programming in C**: An article aimed at beginners, providing a clear introduction to socket programming.

   [DEV.to](https://dev.to/sanjayrv/a-beginners-guide-to-socket-programming-in-c-5an5)
5. **Socket Programming Tutorial In C For Beginners | Part 1 | Eduonix**: A video tutorial that introduces the basics of socket programming in C.

   [YouTube](https://www.youtube.com/watch?v=LtXEMwSG5-8)
6. **Beej's Guide to Network Programming - GitHub Repository**: The source code repository for Beej's Guide, useful for practical examples.

   [GitHub](https://github.com/beejjorgensen/bgnet)
7. **Hands-On Network Programming with C**: A GitHub repository accompanying a book that provides practical examples of network programming in C.

   [GitHub](https://github.com/codeplea/Hands-On-Network-Programming-with-C)

These resources offer a mix of theoretical knowledge and practical examples to help you build a solid foundation in socket programming.
{% endhint %}
