Rewrite in C. Simple TCP listener.

This commit is contained in:
2025-09-13 00:57:47 +03:00
parent 418d33a6de
commit 39db2830e2
9 changed files with 149 additions and 77 deletions

3
.gitignore vendored
View File

@@ -1 +1,4 @@
.idea/
build/
cmake-build-debug/
cmake-build-release/

View File

@@ -2,21 +2,19 @@ cmake_minimum_required(VERSION 3.15...4.0)
project(SimpleHttpServer VERSION 1.0
DESCRIPTION "A simple HTTP server written in C++"
LANGUAGES CXX)
LANGUAGES C)
add_library(
httpserverlib
STATIC
src/server.hpp
src/server.cpp
src/httpserver.h
src/httpserver.c
)
target_compile_features(httpserverlib PUBLIC cxx_std_23)
add_executable(
httpserver
app/main.cpp
app/main.c
app/main.h
)
target_link_libraries(httpserver PUBLIC httpserverlib)

20
app/main.c Normal file
View File

@@ -0,0 +1,20 @@
//
// Created by nazar on 12.09.2025.
//
#include "main.h"
#include <stdio.h>
struct HttpResponse* handleRequest(struct HttpRequest* request)
{
struct HttpResponse* http_response = {};
return http_response;
}
int main() {
struct HttpServer http_server;
printf("Starting the server...\n");
start_http_server(&http_server, ADDRESS, PORT);
printf("Bye!\n");
return 0;
}

View File

@@ -1,8 +0,0 @@
#include <print>
#include "../src/server.hpp"
int main() {
SimpleHttpServer server;
server.start_listening(8080);
std::println("Bye!");
}

16
app/main.h Normal file
View File

@@ -0,0 +1,16 @@
//
// Created by nazar on 12.09.2025.
//
#ifndef SIMPLEHTTPSERVER_MAIN_H
#define SIMPLEHTTPSERVER_MAIN_H
#include "../src/httpserver.h"
#define ADDRESS "127.0.0.1"
#define PORT 8080
struct HttpResponse* handleRequest(struct HttpRequest* request);
int main();
#endif //SIMPLEHTTPSERVER_MAIN_H

66
src/httpserver.c Normal file
View File

@@ -0,0 +1,66 @@
//
// Created by nazar on 12.09.2025.
//
#include "httpserver.h"
#include <stdio.h>
void start_http_server(struct HttpServer* http_server, const char *addr, const short port)
{
const int server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd == -1)
{
printf("Failed to create new socket.\n");
return;
}
struct sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr(addr);
address.sin_port = htons(port);
const int bind_c = bind(server_fd, (struct sockaddr*)&address, sizeof(address));
if (bind_c == -1)
{
printf("Failed to bind address.\n");
return;
}
const int listen_c = listen(server_fd, 3);
if (listen_c == -1)
{
printf("Failed to begin listening.\n");
return;
}
printf("Server is listening on %s:%d...\n", addr, port);
size_t addr_len = sizeof(address);
process_conn(http_server, server_fd, (struct sockaddr*)&address, (socklen_t*)&addr_len);
close(server_fd);
}
void process_conn(struct HttpServer* http_server, const int server_fd, struct sockaddr* address, socklen_t* addr_len)
{
const int socket_d = accept(server_fd, address, addr_len);
if (socket_d == -1)
{
printf("Failed to accept connection.\n");
return;
}
char buffer[1024] = {0};
const ssize_t bytes_read = read(socket_d, buffer, 1024);
printf("Client message (%ld):\n", bytes_read);
for (int i = 0; i < bytes_read; i++)
{
if (buffer[i] == '\r')
continue;
putchar(buffer[i]);
}
putchar('\n');
fflush(stdout);
close(socket_d);
}

36
src/httpserver.h Normal file
View File

@@ -0,0 +1,36 @@
//
// Created by nazar on 12.09.2025.
//
// https://datatracker.ietf.org/doc/html/rfc9112#name-message
#ifndef SIMPLEHTTPSERVER_H
#define SIMPLEHTTPSERVER_H
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
struct HttpRequest
{
};
struct HttpResponse
{
};
struct HttpServer
{
struct HttpResponse* (*handleRequest)(struct HttpRequest* request);
};
void start_http_server(struct HttpServer* http_server, const char *addr, short port);
void process_conn(struct HttpServer* http_server, int server_fd, struct sockaddr* address, socklen_t* addr_len);
#endif //SIMPLEHTTPSERVER_H

View File

@@ -1,34 +0,0 @@
#include "server.hpp"
SimpleHttpServer::SimpleHttpServer() {
}
SimpleHttpServer::~SimpleHttpServer() {
}
void SimpleHttpServer::start_listening(int port) {
std::println("Starting server on port {0}...", port);
int serverSocket = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in serverAddress;
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(port);
serverAddress.sin_addr.s_addr = INADDR_ANY;
bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress));
listen(serverSocket, 5);
std::println("Listening...");
int clientSocket = accept(serverSocket, nullptr, nullptr);
char buffer[1024] = {0};
recv(clientSocket, buffer, sizeof(buffer), 0);
std::println("Received: {0}", buffer);
std::println("Closing...");
close(serverSocket);
}

View File

@@ -1,25 +0,0 @@
#include <stdio.h>
#include <print>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
class SimpleHttpServer {
public:
SimpleHttpServer();
SimpleHttpServer(SimpleHttpServer &&) = default;
SimpleHttpServer(const SimpleHttpServer &) = default;
SimpleHttpServer &operator=(SimpleHttpServer &&) = default;
SimpleHttpServer &operator=(const SimpleHttpServer &) = default;
~SimpleHttpServer();
void start_listening(int port);
private:
};