Hey guys! Let's dive into creating a simple daytime client-server program using C. This is a fundamental example in network programming and will help you grasp the basics of how clients and servers communicate. We'll break down the code step by step, making sure it's easy to understand, even if you're relatively new to C or network programming.
Understanding the Daytime Protocol
Before we jump into the code, it's essential to understand what the Daytime Protocol is all about. The Daytime Protocol (defined in RFC 867) is a very simple protocol where a client connects to a server, and the server sends back the current date and time as a human-readable string. No authentication, no complex data – just a straightforward exchange of information. It operates over TCP (Transmission Control Protocol), ensuring reliable, ordered delivery of data. Think of it as the "Hello, World!" of network programming. The server listens on a specific port (typically port 13), and when a client connects, it sends the current date and time and then closes the connection. This simplicity makes it perfect for learning the basics of client-server communication. Now, you might be wondering why we'd use such an old protocol in today's world. Well, while it may not be practical for real-world applications needing security or complex data transfer, it's incredibly useful for educational purposes. It allows us to focus on the core concepts of socket programming without getting bogged down in complicated features. Plus, it's a fun way to see how network communication works under the hood. Remember, understanding these fundamentals is crucial, as they form the basis for more complex network applications you might build in the future. So, grab your favorite text editor, and let's get started with the code! We'll begin with the server side.
Server-Side Implementation
The server's job is to listen for incoming connections, accept them, send the current date and time, and then close the connection. Here’s the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 13 // Daytime port
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int addrlen = sizeof(address);
char *message;
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
// Binding the socket to the specified port
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
// Listening for incoming connections
if (listen(server_fd, 3) < 0) {
perror("listen failed");
exit(EXIT_FAILURE);
}
printf("Server listening on port %d\n", PORT);
while (1) {
// Accepting incoming connection
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
perror("accept failed");
exit(EXIT_FAILURE);
}
// Get current time
time_t timer;
char buffer[26];
struct tm* tm_info;
time(&timer);
tm_info = localtime(&timer);
strftime(buffer, 26, "%Y-%m-%d %H:%M:%S", tm_info);
message = buffer;
// Sending the message to the client
send(new_socket, message, strlen(message), 0);
printf("Sent: %s\n", message);
// Closing the connection
close(new_socket);
}
return 0;
}
Let’s break this down. First, we include the necessary header files. These provide functions for socket programming, standard input/output, string manipulation, and time management. These are the building blocks of our program. Then, we define the port number (13) that our server will listen on. Next, inside the main function, we declare variables for the server's file descriptor (server_fd), the new socket for each connection (new_socket), and the sockaddr_in structure (address) to hold address information. We create a socket using socket(AF_INET, SOCK_STREAM, 0). AF_INET specifies the IPv4 address family, and SOCK_STREAM indicates a TCP socket. If the socket creation fails, we print an error message and exit. We then populate the address structure with the address family, the IP address (using INADDR_ANY to listen on all available interfaces), and the port number. We bind the socket to the specified address and port using the bind function. If binding fails, we print an error message and exit. The listen function puts the socket in a passive listening mode, waiting for incoming connections. The 3 argument specifies the maximum length of the queue for pending connections. We print a message to the console indicating that the server is listening on the specified port. The while(1) loop allows the server to continuously accept incoming connections. Inside the loop, the accept function accepts a connection, creating a new socket (new_socket) for the connection. If accepting fails, we print an error message and exit. We retrieve the current time using time(&timer) and convert it to a local time structure using localtime(&timer). The strftime function formats the time into a human-readable string, which is stored in the buffer. We assign the buffer to the message pointer. The send function sends the message to the client through the new_socket. We print the sent message to the console for logging purposes. Finally, we close the connection using close(new_socket). This completes the interaction with the client for this connection. The server then loops back to accept another incoming connection. This is a simple, yet robust server implementation that clearly demonstrates the fundamental steps involved in network programming. Each step plays a crucial role in setting up the server and handling client requests.
Client-Side Implementation
Now, let’s create the client-side code that connects to the server and receives the daytime information. Here’s the C code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 13 // Daytime port
int main(int argc, char const *argv[]) {
int sock = 0, valread;
struct sockaddr_in serv_addr;
char buffer[1024] = {0};
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("\n Socket creation error \n");
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0) {
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
printf("\nConnection Failed \n");
return -1;
}
valread = read(sock, buffer, 1024);
printf("%s\n",buffer );
return 0;
}
Alright, let's break down the client-side code. First, we include necessary header files, similar to the server-side. These headers provide functions for socket programming, standard I/O, string manipulation, and network address conversion. We define the port number (13) to connect to. Inside the main function, we declare variables: sock for the socket file descriptor, serv_addr to store the server address, and buffer to hold the received data. Then, we create a socket using socket(AF_INET, SOCK_STREAM, 0). If the socket creation fails, we print an error and exit. We populate the serv_addr structure. sin_family is set to AF_INET for IPv4. The sin_port is set to the Daytime Protocol port (13) using htons to convert it to network byte order. The inet_pton function converts the IP address "127.0.0.1" (localhost) from text to binary form and stores it in serv_addr.sin_addr. If the address conversion fails, we print an error and exit. The connect function establishes a connection to the server. If the connection fails, we print an error and exit. We read the data sent by the server into the buffer using the read function. The number of bytes read is stored in valread. Finally, we print the received data from the buffer to the console. This client-side code is straightforward and concise, demonstrating the essential steps to connect to a server, receive data, and display it. Each step is crucial for establishing a successful connection and retrieving the information from the server. Remember, this is a basic implementation, and more robust error handling and connection management would be needed in a production environment. But for learning purposes, this provides a clear and simple example.
Compiling and Running the Code
To compile the server and client code, you'll need a C compiler (like GCC). Save the server code in a file named server.c and the client code in client.c. Open your terminal and use the following commands:
gcc server.c -o server
gcc client.c -o client
These commands compile the C code and create executable files named server and client. To run the server, simply execute the server executable in one terminal window:
./server
The server will start listening on port 13. In a separate terminal window, run the client executable:
./client
The client will connect to the server, receive the current date and time, and print it to the console. If everything goes well, you should see the server output in its terminal, confirming that it sent the time, and the client output in its terminal, showing the received time. If you encounter any errors, double-check the code for typos and ensure that the server is running before you start the client. This compilation and execution process allows you to see the client-server interaction in action, reinforcing your understanding of network programming concepts. Remember, practice makes perfect, so try experimenting with the code and adding more features to solidify your knowledge.
Conclusion
Alright guys, that's it! You've successfully created a simple daytime client-server program in C. This example, while basic, illustrates the fundamental concepts of network programming: socket creation, binding, listening, accepting connections, sending and receiving data, and closing connections. By understanding these concepts, you'll be well-equipped to tackle more complex network applications. Remember that the Daytime Protocol, though simple, is a fantastic tool for learning. Now, go forth and build some awesome networked applications! Keep experimenting and happy coding!
Lastest News
-
-
Related News
20% Down Payment: Is It The Right Choice?
Alex Braham - Nov 13, 2025 41 Views -
Related News
2008 Lexus GS 350 AWD: Common Problems To Watch For
Alex Braham - Nov 13, 2025 51 Views -
Related News
OSCP & PSSI: Career Paths In Accounting
Alex Braham - Nov 13, 2025 39 Views -
Related News
Copa America 2027: Discover The Host Nation!
Alex Braham - Nov 9, 2025 44 Views -
Related News
Pausanias: The Man Who Founded Sparta
Alex Braham - Nov 12, 2025 37 Views