Hey guys! Today, we're diving into creating a simple daytime client-server program in C. This is a fantastic project for understanding basic network programming concepts. We'll break down the server and client code step-by-step, making it super easy to follow along. So, grab your favorite IDE, and let's get started!
Understanding the Daytime Protocol
Before we jump into the code, let's quickly chat about the Daytime Protocol. The Daytime Protocol is a very straightforward network protocol. Its sole purpose is to provide the current date and time to any client that requests it. Typically, it operates over TCP (Transmission Control Protocol) on port 13. The server listens for incoming connections on this port, and when a client connects, the server sends back a human-readable string containing the date and time. It's that simple!
This protocol is excellent for learning because it minimizes complexity. There's no need for complex data encoding or authentication. The server simply needs to know how to get the current date and time and how to send it over a network connection. For the client, it just needs to connect to the server and receive the data. This simplicity makes it an ideal starting point for anyone venturing into network programming.
Furthermore, working with the Daytime Protocol helps you understand essential networking concepts, such as socket creation, binding, listening, accepting connections (on the server-side), connecting to a server (on the client-side), sending data, and receiving data. These concepts are fundamental building blocks for more complex network applications. So, even though the Daytime Protocol itself is quite basic, mastering it lays a solid foundation for your future network programming endeavors. Let's get our hands dirty and start coding!
Server-Side Implementation
Alright, let's begin with the server-side implementation. The server's job is to listen for incoming connections, accept them, get the current date and time, and send it back to the client. Here's a breakdown of the code:
Setting up the Server Socket
First, we need to create a socket. A socket is essentially an endpoint for network communication. Think of it as a door through which data flows in and out of our server.
#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 Protocol Port
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int addrlen = sizeof(address);
// 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 our specified IP and port
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
// Listen for incoming connections
if (listen(server_fd, 3) < 0) {
perror("listen failed");
exit(EXIT_FAILURE);
}
In this snippet, we include necessary header files for socket programming. We define the port number (13 for the Daytime Protocol). We create a socket using socket(), specifying the address family (AF_INET for IPv4), socket type (SOCK_STREAM for TCP), and protocol (0 for default). We then set up the server address, binding it to any available IP address on the machine and the specified port. Finally, we start listening for incoming connections using listen(). The 3 in listen(server_fd, 3) indicates the maximum number of queued connections.
Handling Client Connections
Once the server is listening, it needs to accept incoming connections. When a client connects, the server creates a new socket specifically for that connection. This allows the server to handle multiple clients simultaneously.
printf("Server listening on port %d\n", PORT);
while (1) {
// Accept 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 rawtime;
struct tm *timeinfo;
char buffer[80];
time(&rawtime);
timeinfo = localtime(&rawtime);
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", timeinfo);
// Send time to client
send(new_socket, buffer, strlen(buffer), 0);
printf("Sent time to client: %s\n", buffer);
// Close the socket
close(new_socket);
}
return 0;
}
Inside the while(1) loop, the server continuously waits for incoming connections using accept(). When a connection is accepted, a new socket (new_socket) is created for that specific client. We then get the current date and time using time(), localtime(), and strftime() to format it into a human-readable string. Finally, we send the formatted time string to the client using send() and close the connection using close(). The server then loops back to wait for the next incoming connection. This process continues indefinitely, allowing the server to handle multiple clients one after another.
Client-Side Implementation
Now, let's move on to the client-side. The client's job is to connect to the server, receive the date and time, and display it to the user.
Setting up the Client Socket
The client code is similar to the server code in terms of setting up the socket, but instead of listening for connections, it actively connects to the server.
#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 Protocol Port
int main(int argc, char const *argv[]) {
int sock = 0;
struct sockaddr_in serv_addr;
char buffer[1024] = {0};
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("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("Invalid address/ Address not supported \n");
return -1;
}
Here, we create a socket just like we did on the server-side. We set up the server address, specifying the address family (AF_INET), port number (13), and the IP address of the server (in this case, we're using 127.0.0.1, which is the loopback address, meaning the client and server are running on the same machine). The inet_pton() function converts the IP address from text format to binary format.
Connecting to the Server and Receiving Data
Once the socket is set up, the client attempts to connect to the server. After a successful connection, it receives the date and time sent by the server.
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
printf("Connection Failed \n");
return -1;
}
read(sock, buffer, 1024);
printf("Received time from server: %s\n", buffer);
close(sock);
return 0;
}
We use the connect() function to establish a connection to the server. If the connection is successful, the read() function is used to receive data from the server. The received data (which is the date and time string) is stored in the buffer. Finally, we print the received time to the console and close the socket.
Compiling and Running the Code
To compile the server and client code, you can use a C compiler like GCC. Here are the commands:
gcc server.c -o server
gcc client.c -o client
First, compile the server.c file and create an executable named server. Then, compile the client.c file and create an executable named client. Make sure you have GCC installed on your system. If not, you can install it using your system's package manager (e.g., apt-get install gcc on Debian/Ubuntu or brew install gcc on macOS).
To run the code, first, execute the server:
./server
This will start the server, and it will begin listening for incoming connections on port 13. Keep the server running in one terminal. Then, in another terminal, execute the client:
./client
The client will connect to the server, receive the date and time, display it on the console, and then exit. You should see the current date and time printed on both the server and client consoles.
If you encounter any issues, make sure that the server is running before you start the client. Also, double-check that the port number is correctly configured in both the server and client code. If you are running the server and client on different machines, you'll need to replace 127.0.0.1 in the client code with the actual IP address of the server.
Potential Improvements
While this is a basic implementation, there are several ways to improve it:
- Error Handling: Add more robust error handling to catch potential issues like network errors or invalid input.
- Multi-threading: Implement multi-threading on the server-side to handle multiple clients concurrently without blocking.
- Configuration: Allow the port number and server IP address to be configurable via command-line arguments.
- Logging: Add logging functionality to the server to record client connections and any errors that occur.
Conclusion
And there you have it! A simple daytime client-server program in C. This project provides a solid foundation for understanding network programming concepts. Feel free to experiment with the code, add new features, and explore more complex network protocols. Happy coding, and always remember to have fun while you learn! This foundational knowledge will set you up for tackling more complex network applications in the future. Keep experimenting, and who knows, you might just build the next big thing in networking! Until next time, happy coding!
Lastest News
-
-
Related News
Logos In Tech: Why They Matter
Alex Braham - Nov 13, 2025 30 Views -
Related News
Typhoon In Davao Today? Get The Latest Updates!
Alex Braham - Nov 12, 2025 47 Views -
Related News
Adultery Laws In New Mexico: Is It Illegal?
Alex Braham - Nov 13, 2025 43 Views -
Related News
Password Reset Meaning In Hindi? Explained!
Alex Braham - Nov 13, 2025 43 Views -
Related News
Reliable Used Mitsubishi Outlander: What To Know
Alex Braham - Nov 13, 2025 48 Views