Created
January 19, 2012 21:06
Toy http server in C
This file contains 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
#include <stdio.h> | |
#include <stdlib.h> | |
#include <strings.h> | |
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <unistd.h> | |
int httpd_listen(unsigned short int port) { | |
int sock; | |
struct sockaddr_in name; | |
sock = socket(PF_INET, SOCK_STREAM, 0); | |
if(sock < 0) { | |
perror("socket"); | |
exit(EXIT_FAILURE); | |
} | |
name.sin_family = AF_INET; | |
name.sin_port = htons(port); | |
name.sin_addr.s_addr = htonl(INADDR_ANY); | |
if(bind(sock, (struct sockaddr*)&name, sizeof(name)) < 0) { | |
perror("bind"); | |
exit(EXIT_FAILURE); | |
} | |
return sock; | |
} | |
void httpd_handle_client(int client_sock) { | |
//char[1024] buffer; | |
char byte; | |
int size, sent; | |
int newlines = 0; | |
const char response[] = "200 OK\n\nHello client!\n"; | |
const char response_size = strlen(response); | |
while(1) { | |
size = recv(client_sock, &byte, sizeof(byte), 0); | |
if(size < 0) { | |
perror("recv"); | |
exit(EXIT_FAILURE); | |
} | |
if(size > 0) { | |
putchar(byte); | |
} | |
if(byte == '\n') { | |
newlines += 1; | |
} | |
else { | |
if(byte != '\r') { | |
newlines = 0; | |
} | |
} | |
if(newlines == 2) { | |
sent = 0; | |
while(1) { | |
size = send(client_sock, response + sent, response_size - sent, 0); | |
if(size < 0) { | |
perror("send"); | |
exit(EXIT_FAILURE); | |
} | |
sent += size; | |
if(size >= response_size) { | |
close(client_sock); | |
return; | |
} | |
} | |
} | |
} | |
} | |
int main() { | |
int listen_sock, client_sock; | |
const unsigned short int port = 6000; | |
const int listen_backlog = 10; | |
struct sockaddr_in client_addr; | |
socklen_t client_length; | |
listen_sock = httpd_listen(port); | |
printf("listening on port %d\n", port); | |
if(listen(listen_sock, listen_backlog) < 0) { | |
perror("listen"); | |
exit(EXIT_FAILURE); | |
} | |
client_sock = accept(listen_sock, | |
(struct sockaddr*)&client_addr, | |
&client_length); | |
if(client_sock < 0) { | |
perror("accept"); | |
exit(EXIT_FAILURE); | |
} | |
httpd_handle_client(client_sock); | |
exit(EXIT_SUCCESS); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment