Skip to content

Instantly share code, notes, and snippets.

@i-rebel-aj
Created February 23, 2024 07:15
Show Gist options
  • Save i-rebel-aj/c2eb2e3013f1d3fe0b69ee22aa337269 to your computer and use it in GitHub Desktop.
Save i-rebel-aj/c2eb2e3013f1d3fe0b69ee22aa337269 to your computer and use it in GitHub Desktop.
A simple single threaded webserver written in C
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<signal.h>
#include <netinet/in.h>
//Maximum Application Buffer
/**
Max Amount of memory from network (Request Size)
*/
#define APP_MAX_BUFFER 1024
#define PORT 3001
#define MAX_BACKLOG_QUEUE_SIZE 10
#define SUCCESS_RESPONSE "HTTP/1.1 200 OK\r\nContent-Length: 12\r\nContent-Type: text/plain\r\n\r\nHello World\n"
/**
Single Threaded HTTP Webserver
*/
void send_response(int server_fd){
struct sockaddr_in client_address;
int clinet_address_len=sizeof(client_address);
int client_fd=accept(server_fd, (struct sockaddr *)&client_address, (socklen_t *)&clinet_address_len);
if(client_fd==-1){
perror("Accept Failed");
exit(EXIT_FAILURE);
}
char buffer[APP_MAX_BUFFER]={0};
if(read(client_fd, buffer, APP_MAX_BUFFER)==-1){
perror("Request can not read to buffer\n");
}
printf("The request is:\n%s\n", buffer);
write(client_fd, SUCCESS_RESPONSE, strlen(SUCCESS_RESPONSE));
close(client_fd);
}
int main(){
//Define socket address
struct sockaddr_in server_address;
int server_fd=socket(AF_INET, SOCK_STREAM, 0);
if(server_fd==-1){
perror("Socket Failed");
exit(EXIT_FAILURE);
}
/**
Make Socket Reusable Even if server is closed
*/
int opt = 1;
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
server_address.sin_family=AF_INET; //ipv4
server_address.sin_port= htons(PORT) ;
server_address.sin_addr.s_addr= INADDR_ANY; //Listening 0.0.0.0 inefraces
if(bind(server_fd, (struct sockaddr *)&server_address, sizeof(server_address))<0){
perror("Bind Failed");
exit(EXIT_FAILURE);
}
//Creates the Queue
//Listen for clients, with 10 backlog (10 connections in accept queue)
if(listen(server_fd,MAX_BACKLOG_QUEUE_SIZE )){
perror("Listen Failed");
exit(EXIT_FAILURE);
}
printf("Server running, press Ctrl+C to exit...\n");
while(1){
printf("Waiting for connection\n");
send_response(server_fd);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment