Skip to content

Instantly share code, notes, and snippets.

@umputun
Created February 3, 2024 22:18
Show Gist options
  • Save umputun/9992a1747b9080ea2f301a6f37822aec to your computer and use it in GitHub Desktop.
Save umputun/9992a1747b9080ea2f301a6f37822aec to your computer and use it in GitHub Desktop.
pong server
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#define PORT 8080
#define BUFFER_SIZE 1024
#define REQUEST_INTERVAL 500000 // 500 milliseconds in microseconds
void handleConnection(int newSocket, const char *info) {
char buffer[BUFFER_SIZE] = {0}; // Initialize buffer to zeros
char response[2048];
ssize_t bytesRead = read(newSocket, buffer, BUFFER_SIZE - 1); // Leave space for null terminator
if (bytesRead < 0) {
perror("read");
return;
}
buffer[bytesRead] = '\0'; // Null-terminate the buffer
if (strstr(buffer, "GET /ping HTTP/1.1")) {
snprintf(response, sizeof(response),
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html; charset=UTF-8\r\n"
"Server: %s\r\n\r\n"
"pong\r\n", info);
} else {
snprintf(response, sizeof(response),
"HTTP/1.1 404 Not Found\r\n"
"Content-Type: text/html; charset=UTF-8\r\n"
"Server: %s\r\n\r\n"
"Not Found\r\n", info);
}
send(newSocket, response, strlen(response), 0);
close(newSocket);
}
int main(int argc, char *argv[]) {
int serverFd, newSocket;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
if (argc < 2) {
printf("Usage: %s <server-info>\n", argv[0]);
return 1;
}
const char *info = argv[1];
serverFd = socket(AF_INET, SOCK_STREAM, 0);
if (serverFd == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
if (setsockopt(serverFd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
if (bind(serverFd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(serverFd, 10) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
struct timeval lastRequestTime, currentTime;
gettimeofday(&lastRequestTime, NULL); // Initialize lastRequestTime
printf("pong server is running for %s\n", info);
while (1) {
newSocket = accept(serverFd, (struct sockaddr *)&address, (socklen_t*)&addrlen);
if (newSocket < 0) {
perror("accept");
continue;
}
gettimeofday(&currentTime, NULL);
long elapsed = (currentTime.tv_sec - lastRequestTime.tv_sec) * 1000000L
+ (currentTime.tv_usec - lastRequestTime.tv_usec);
if (elapsed < REQUEST_INTERVAL) {
usleep(REQUEST_INTERVAL - elapsed); // Delay the response
}
lastRequestTime = currentTime;
handleConnection(newSocket, info);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment