Skip to content

Instantly share code, notes, and snippets.

@littlefuntik
Created May 7, 2019 14:27
Show Gist options
  • Save littlefuntik/7f7e7c48f093a6fa00475a1d044d4647 to your computer and use it in GitHub Desktop.
Save littlefuntik/7f7e7c48f093a6fa00475a1d044d4647 to your computer and use it in GitHub Desktop.
Web server example written on C language (Mac OS)
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
// global constants
#define PORT 8080 // port to connect on
#define LISTENQ 10 // number of connections
int list_s; // listening socket
// clean up listening socket on ctrl-c
void cleanup(int sig)
{
printf("Cleaning up connections and exiting.\n");
// try to close the listening socket
if (close(list_s) < 0)
{
fprintf(stderr, "Error calling close()\n");
exit(EXIT_FAILURE);
}
// exit with success
exit(EXIT_SUCCESS);
}
int main()
{
int conn_s;
struct sockaddr_in servaddr;
char send_buffer[1025];
// set up signal handler for ctrl-c
(void)signal(SIGINT, cleanup);
// socket create and verification
if ((list_s = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
fprintf(stderr, "Error creating listening socket.\n");
exit(EXIT_FAILURE);
}
// set all bytes in socket address structure to zero
memset(&servaddr, 0, sizeof(servaddr));
// assign IP, PORT
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
// binding newly created socket to given IP and verification
if (bind(list_s, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0)
{
fprintf(stderr, "Error calling bind()\n");
exit(EXIT_FAILURE);
}
// now server is ready to listen and verification
if ((listen(list_s, LISTENQ)) == -1)
{
fprintf(stderr, "Error Listening\n");
exit(EXIT_FAILURE);
}
// Size of the address
int addrlen = sizeof(servaddr);
memset(send_buffer, 0, sizeof(send_buffer));
snprintf(send_buffer, sizeof(send_buffer), "HTTP/1.1 200 OK\nContent-Type: text/html\nContent-Length: 21\n\n<b>Hello, world!</b>\n");
// Have the child loop infinetly dealing with a connection then getting the next one in the queue
while (1)
{
// Accept a connection
conn_s = accept(list_s, (struct sockaddr *)&servaddr, (socklen_t *)&addrlen);
// If something went wrong with accepting the connection deal with it
if (conn_s == -1)
{
fprintf(stderr, "Error accepting connection\n");
exit(EXIT_FAILURE);
}
// buffer 1M
char buffer[1024*1024] = {0};
long valread = read( conn_s , buffer, 1024*1024);
write(conn_s, send_buffer, strlen(send_buffer));
// Close the connection now were done
close(conn_s);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment