Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Aprende Graceful Shutdown | Advanced Networking Techniques
C Networking Basics

bookGraceful Shutdown

When working with network programs in C, it is essential to handle the shutdown process carefully to avoid resource leaks and undefined behavior. Properly closing sockets and cleaning up resources ensures that your application does not leave open file descriptors, which could eventually exhaust system resources and prevent new connections from being established. When a socket is no longer needed, you must signal the end of communication, gracefully close the connection, and release any resources associated with it. This involves using the shutdown() function to indicate that you have finished sending or receiving data, followed by the close() function to free the socket descriptor.

graceful_shutdown.c

graceful_shutdown.c

copy
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #include <netinet/in.h> #define PORT 8080 void run_server() { int server_fd, client_fd; struct sockaddr_in address; socklen_t addrlen = sizeof(address); char buffer[1024] = {0}; server_fd = socket(AF_INET, SOCK_STREAM, 0); if (server_fd < 0) { perror("Server socket failed"); exit(EXIT_FAILURE); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("Bind failed"); close(server_fd); exit(EXIT_FAILURE); } if (listen(server_fd, 1) < 0) { perror("Listen failed"); close(server_fd); exit(EXIT_FAILURE); } printf("Server listening on port %d...\n", PORT); client_fd = accept(server_fd, (struct sockaddr *)&address, &addrlen); if (client_fd < 0) { perror("Accept failed"); close(server_fd); exit(EXIT_FAILURE); } int valread = read(client_fd, buffer, sizeof(buffer)); printf("Server received: %s\n", buffer); // Graceful shutdown: stop further sends and receives shutdown(client_fd, SHUT_RDWR); close(client_fd); close(server_fd); printf("Server sockets closed gracefully.\n"); } void run_client() { int sock; struct sockaddr_in serv_addr; char *message = "Hello, server!"; sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { perror("Client socket failed"); exit(EXIT_FAILURE); } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) { perror("Invalid address"); close(sock); exit(EXIT_FAILURE); } if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { perror("Connection failed"); close(sock); exit(EXIT_FAILURE); } send(sock, message, strlen(message), 0); // Graceful shutdown: stop further sends and receives shutdown(sock, SHUT_RDWR); close(sock); printf("Client socket closed gracefully.\n"); } int main(int argc, char const *argv[]) { if (argc != 2) { printf("Usage: %s [server|client]\n", argv[0]); return 1; } if (strcmp(argv[1], "server") == 0) { run_server(); } else if (strcmp(argv[1], "client") == 0) { run_client(); } else { printf("Unknown role: %s\n", argv[1]); return 1; } return 0; }

This program shows a simple TCP client–server interaction in C. The server creates a socket, binds to port 8080, listens for a connection, accepts a client, reads the message, and then shuts down cleanly. The client creates a socket, connects to 127.0.0.1:8080, sends a short message, and closes the connection. Together, they demonstrate the basic TCP workflow: socket creation, connection, data transfer, and graceful shutdown.

Note
Note

This example handles only one client and does not echo the message back to the client. In a real TCP echo server, the server would send the received data back before closing the connection.

question mark

What is the main reason for calling close() on a socket in C networking?

Select the correct answer

¿Todo estuvo claro?

¿Cómo podemos mejorarlo?

¡Gracias por tus comentarios!

Sección 3. Capítulo 2

Pregunte a AI

expand

Pregunte a AI

ChatGPT

Pregunte lo que quiera o pruebe una de las preguntas sugeridas para comenzar nuestra charla

bookGraceful Shutdown

Desliza para mostrar el menú

When working with network programs in C, it is essential to handle the shutdown process carefully to avoid resource leaks and undefined behavior. Properly closing sockets and cleaning up resources ensures that your application does not leave open file descriptors, which could eventually exhaust system resources and prevent new connections from being established. When a socket is no longer needed, you must signal the end of communication, gracefully close the connection, and release any resources associated with it. This involves using the shutdown() function to indicate that you have finished sending or receiving data, followed by the close() function to free the socket descriptor.

graceful_shutdown.c

graceful_shutdown.c

copy
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #include <netinet/in.h> #define PORT 8080 void run_server() { int server_fd, client_fd; struct sockaddr_in address; socklen_t addrlen = sizeof(address); char buffer[1024] = {0}; server_fd = socket(AF_INET, SOCK_STREAM, 0); if (server_fd < 0) { perror("Server socket failed"); exit(EXIT_FAILURE); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("Bind failed"); close(server_fd); exit(EXIT_FAILURE); } if (listen(server_fd, 1) < 0) { perror("Listen failed"); close(server_fd); exit(EXIT_FAILURE); } printf("Server listening on port %d...\n", PORT); client_fd = accept(server_fd, (struct sockaddr *)&address, &addrlen); if (client_fd < 0) { perror("Accept failed"); close(server_fd); exit(EXIT_FAILURE); } int valread = read(client_fd, buffer, sizeof(buffer)); printf("Server received: %s\n", buffer); // Graceful shutdown: stop further sends and receives shutdown(client_fd, SHUT_RDWR); close(client_fd); close(server_fd); printf("Server sockets closed gracefully.\n"); } void run_client() { int sock; struct sockaddr_in serv_addr; char *message = "Hello, server!"; sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { perror("Client socket failed"); exit(EXIT_FAILURE); } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) { perror("Invalid address"); close(sock); exit(EXIT_FAILURE); } if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { perror("Connection failed"); close(sock); exit(EXIT_FAILURE); } send(sock, message, strlen(message), 0); // Graceful shutdown: stop further sends and receives shutdown(sock, SHUT_RDWR); close(sock); printf("Client socket closed gracefully.\n"); } int main(int argc, char const *argv[]) { if (argc != 2) { printf("Usage: %s [server|client]\n", argv[0]); return 1; } if (strcmp(argv[1], "server") == 0) { run_server(); } else if (strcmp(argv[1], "client") == 0) { run_client(); } else { printf("Unknown role: %s\n", argv[1]); return 1; } return 0; }

This program shows a simple TCP client–server interaction in C. The server creates a socket, binds to port 8080, listens for a connection, accepts a client, reads the message, and then shuts down cleanly. The client creates a socket, connects to 127.0.0.1:8080, sends a short message, and closes the connection. Together, they demonstrate the basic TCP workflow: socket creation, connection, data transfer, and graceful shutdown.

Note
Note

This example handles only one client and does not echo the message back to the client. In a real TCP echo server, the server would send the received data back before closing the connection.

question mark

What is the main reason for calling close() on a socket in C networking?

Select the correct answer

¿Todo estuvo claro?

¿Cómo podemos mejorarlo?

¡Gracias por tus comentarios!

Sección 3. Capítulo 2
some-alt