Created
June 23, 2025 17:38
-
-
Save Hermann-SW/c63c88040276b135a600a440d23520ad to your computer and use it in GitHub Desktop.
single threaded http server for distribution of disjoint bases from a range to geneferg on many CPUs/GPUs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* based on: | |
https://medium.com/@justup1080/tutorial-creating-a-minimalist-http-server-in-c-2303d140c725 | |
gcc -Wall -Wextra -pedantic range_http.c -o range_http | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <netinet/in.h> | |
#include <assert.h> | |
#define BUFFER_SIZE 16000 | |
struct Server { | |
int domain; | |
int port; | |
int service; | |
int protocol; | |
int backlog; | |
u_long interface; | |
int socket; | |
struct sockaddr_in address; | |
void (*launch)(struct Server *server); | |
}; | |
struct Server server_Constructor(int domain, int port, int service, int protocol, int backlog, u_long interface, void (*launch)(struct Server *server)) { | |
struct Server server; | |
server.domain = domain; | |
server.service = service; | |
server.port = port; | |
server.protocol = protocol; | |
server.backlog = backlog; | |
server.address.sin_family = domain; | |
server.address.sin_port = htons(port); | |
server.address.sin_addr.s_addr = htonl(interface); | |
server.socket = socket(domain, service, protocol); | |
if (server.socket < 0) { | |
perror("Failed to initialize/connect to socket...\n"); | |
exit(EXIT_FAILURE); | |
} | |
if (bind(server.socket, (struct sockaddr*)&server.address, sizeof(server.address)) < 0) { | |
perror("Failed to bind socket...\n"); | |
exit(EXIT_FAILURE); | |
} | |
if (listen(server.socket, server.backlog) < 0) { | |
perror("Failed to start listening...\n"); | |
exit(EXIT_FAILURE); | |
} | |
server.launch = launch; | |
return server; | |
} | |
int begin=0; | |
int end=0; | |
int step=0; | |
void launch(struct Server *server) { | |
char buffer[BUFFER_SIZE]; | |
while (1) { | |
if ((step>0 && begin>=end) || (step<0 && begin<=end)) | |
exit(0); | |
// printf("=== WAITING FOR CONNECTION === \n"); | |
int addrlen = sizeof(server->address); | |
int new_socket = accept(server->socket, (struct sockaddr*)&server->address, (socklen_t*)&addrlen); | |
ssize_t bytesRead = read(new_socket, buffer, BUFFER_SIZE - 1); | |
if (bytesRead >= 0) { | |
buffer[bytesRead] = '\0'; // Null terminate the string | |
putchar('.'); fflush(stdout); // puts(buffer); | |
} else { | |
perror("Error reading buffer...\n"); | |
} | |
sprintf(buffer,"HTTP/1.1 200 OK\r\n\r\n%d\n",begin); | |
begin+=step; | |
write(new_socket, buffer, strlen(buffer)); | |
close(new_socket); | |
} | |
} | |
int main(int argc, char *argv[]) { | |
assert(argc == 5); | |
int port = atoi(argv[1]); | |
begin = atoi(argv[2]); | |
end = atoi(argv[3]); | |
step = atoi(argv[4]); | |
struct Server server = server_Constructor(AF_INET, port, SOCK_STREAM, 0, 10, INADDR_ANY, launch); | |
server.launch(&server); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
range_http arguments are localhost port, from, to and increment.
Half-open range including from and excluding to is generated.
This script demonstrates the use:
Even numbers from 10 to 18:
Even numbers from 20 down to 12: