Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Learn 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

Everything was clear?

How can we improve it?

Thanks for your feedback!

SectionΒ 3. ChapterΒ 2

Ask AI

expand

Ask AI

ChatGPT

Ask anything or try one of the suggested questions to begin our chat

Suggested prompts:

Can you explain the difference between shutdown() and close() in socket programming?

What happens if I don't properly close sockets in my C network program?

Can you provide an example of how to use shutdown() and close() in a C program?

bookGraceful Shutdown

Swipe to show menu

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

Everything was clear?

How can we improve it?

Thanks for your feedback!

SectionΒ 3. ChapterΒ 2
some-alt