mirror of
https://github.com/Mercantec-GHC/h5-projekt-mst.git
synced 2026-08-27 05:37:39 +02:00
impl tcp.cpp
This commit is contained in:
parent
ac8d2f2013
commit
fca446d8e9
@ -1,54 +1,54 @@
|
|||||||
|
|
||||||
MAKEFLAGS += -j16
|
MAKEFLAGS += -j16
|
||||||
|
|
||||||
CC=gcc
|
CXX=g++
|
||||||
LD=gcc
|
LD=g++
|
||||||
CLANG_FORMAT=clang-format
|
CLANG_FORMAT=clang-format
|
||||||
|
|
||||||
CFLAGS = -std=c23 -pedantic-errors -Wall -Wextra -Wconversion
|
CXXFLAGS = -std=c++23 -pedantic-errors -Wall -Wextra -Wconversion
|
||||||
LDFLAGS =
|
LDFLAGS =
|
||||||
|
|
||||||
libraries = libmicrohttpd
|
# libraries = ""
|
||||||
|
|
||||||
CFLAGS += $(shell pkg-config $(libraries) --cflags)
|
# CXXFLAGS += $(shell pkg-config $(libraries) --cflags)
|
||||||
LDFLAGS += $(shell pkg-config $(libraries) --libs)
|
# LDFLAGS += $(shell pkg-config $(libraries) --libs)
|
||||||
|
|
||||||
RELEASE = 0
|
RELEASE = 0
|
||||||
GDB = 0
|
GDB = 0
|
||||||
|
|
||||||
ifeq ($(RELEASE),1)
|
ifeq ($(RELEASE),1)
|
||||||
CFLAGS += -O3
|
CXXFLAGS += -O3
|
||||||
else
|
else
|
||||||
CFLAGS += -g -Wno-unused
|
CXXFLAGS += -g -Wno-unused
|
||||||
|
|
||||||
ifeq ($(GDB),1)
|
ifeq ($(GDB),1)
|
||||||
CFLAGS += -ggdb
|
CXXFLAGS += -ggdb
|
||||||
else
|
else
|
||||||
CFLAGS += -fsanitize=address
|
CXXFLAGS += -fsanitize=address
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
NO_MAIN = 0
|
NO_MAIN = 0
|
||||||
ifeq ($(NO_MAIN),1)
|
ifeq ($(NO_MAIN),1)
|
||||||
CFLAGS += -Dmain="not_main"
|
CXXFLAGS += -Dmain="not_main"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
build_dir = build
|
build_dir = build
|
||||||
obj_dir = $(build_dir)/obj
|
obj_dir = $(build_dir)/obj
|
||||||
|
|
||||||
sources = \
|
sources = \
|
||||||
src/main.c
|
src/main.cpp
|
||||||
|
|
||||||
target=$(build_dir)/backend
|
target=$(build_dir)/backend
|
||||||
|
|
||||||
all: $(target)
|
all: $(target)
|
||||||
|
|
||||||
$(target): $(sources:%.c=$(obj_dir)/%.o)
|
$(target): $(sources:%.cpp=$(obj_dir)/%.o)
|
||||||
$(LD) -o $@ $(CFLAGS) $(LDFLAGS) $^
|
$(LD) -o $@ $(CXXFLAGS) $(LDFLAGS) $^
|
||||||
|
|
||||||
$(obj_dir)/%.o: %.c
|
$(obj_dir)/%.o: %.cpp
|
||||||
@mkdir -p $(dir $@)
|
@mkdir -p $(dir $@)
|
||||||
$(CC) $< -c -o $@ -MMD -MP $(CFLAGS)
|
$(CXX) $< -c -o $@ -MMD -MP $(CXXFLAGS)
|
||||||
|
|
||||||
format:
|
format:
|
||||||
$(CLANG_FORMAT) -style=file -i src/*
|
$(CLANG_FORMAT) -style=file -i src/*
|
||||||
@ -59,5 +59,5 @@ check:
|
|||||||
clean:
|
clean:
|
||||||
rm -rf $(build_dir)
|
rm -rf $(build_dir)
|
||||||
|
|
||||||
-include $(sources:%.c=$(obj_dir)/%.d)
|
-include $(sources:%.cpp=$(obj_dir)/%.d)
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
-xc
|
-xc++
|
||||||
-std=c23
|
-std=c++23
|
||||||
-pedantic-errors
|
-pedantic-errors
|
||||||
-Wall
|
-Wall
|
||||||
-Wextra
|
-Wextra
|
||||||
|
|||||||
@ -1,60 +0,0 @@
|
|||||||
#include <microhttpd.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/select.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#define PORT 8888
|
|
||||||
|
|
||||||
int print_out_key(
|
|
||||||
void* cls, enum MHD_ValueKind kind, const char* key, const char* value)
|
|
||||||
{
|
|
||||||
printf("%s: %s\n", key, value);
|
|
||||||
return MHD_YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
int answer_to_connection(void* cls, struct MHD_Connection* connection,
|
|
||||||
const char* url, const char* method, const char* version,
|
|
||||||
const char* upload_data, size_t* upload_data_size, void** req_cls)
|
|
||||||
{
|
|
||||||
const char* page = "<html><body>Hello, browser!</body></html>";
|
|
||||||
struct MHD_Response* response;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
MHD_get_connection_values(connection,
|
|
||||||
MHD_HEADER_KIND,
|
|
||||||
(MHD_KeyValueIterator)&print_out_key,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
printf("New %s request for %s using version %s\n", method, url, version);
|
|
||||||
|
|
||||||
response = MHD_create_response_from_buffer(
|
|
||||||
strlen(page), (void*)page, MHD_RESPMEM_PERSISTENT);
|
|
||||||
|
|
||||||
ret = (int)MHD_queue_response(connection, MHD_HTTP_OK, response);
|
|
||||||
MHD_destroy_response(response);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
printf("hello\n");
|
|
||||||
struct MHD_Daemon* daemon;
|
|
||||||
|
|
||||||
daemon = MHD_start_daemon(MHD_USE_INTERNAL_POLLING_THREAD,
|
|
||||||
PORT,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
(MHD_AccessHandlerCallback)&answer_to_connection,
|
|
||||||
NULL,
|
|
||||||
MHD_OPTION_END);
|
|
||||||
|
|
||||||
if (NULL == daemon)
|
|
||||||
return 1;
|
|
||||||
getchar();
|
|
||||||
|
|
||||||
MHD_stop_daemon(daemon);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
12
backend/src/main.cpp
Normal file
12
backend/src/main.cpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#define PORT 8888
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
printf("hello\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
78
backend/src/tcp.cpp
Normal file
78
backend/src/tcp.cpp
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#include "tcp.hpp"
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <expected>
|
||||||
|
#include <format>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
namespace mst {
|
||||||
|
auto errno_shim(std::string_view message) -> std::string
|
||||||
|
{
|
||||||
|
auto x = strerror(errno);
|
||||||
|
return std::format("{} ({})", message, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto TcpConnection::write(uint8_t* buffer, size_t len) -> Result<size_t>
|
||||||
|
{
|
||||||
|
ssize_t bytes_written = ::write(this->fd, buffer, len);
|
||||||
|
if (bytes_written < 0) {
|
||||||
|
return std::unexpected(errno_shim("could not write bytes"));
|
||||||
|
}
|
||||||
|
return bytes_written;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto TcpConnection::read(uint8_t* buffer, size_t len) -> Result<size_t>
|
||||||
|
{
|
||||||
|
ssize_t bytes_read = ::recv(this->fd, buffer, len, 0);
|
||||||
|
if (bytes_read < 0) {
|
||||||
|
return std::unexpected(errno_shim("could not read bytes"));
|
||||||
|
}
|
||||||
|
return bytes_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto TcpListener::bind(const std::string& host, uint16_t port)
|
||||||
|
-> Result<TcpListener>
|
||||||
|
{
|
||||||
|
int socket_fd = 0;
|
||||||
|
if ((socket_fd = ::socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
||||||
|
return std::unexpected(errno_shim("could not get socket"));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in address = {
|
||||||
|
.sin_family = AF_INET,
|
||||||
|
.sin_port = htons(port),
|
||||||
|
.sin_addr = in_addr { .s_addr = inet_addr(host.c_str()) },
|
||||||
|
.sin_zero = { },
|
||||||
|
};
|
||||||
|
|
||||||
|
if (::bind(socket_fd, (struct sockaddr*)&address, sizeof(address)) < 0) {
|
||||||
|
return std::unexpected(errno_shim("could not bind"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (::listen(socket_fd, 0) < 0) {
|
||||||
|
return std::unexpected(errno_shim("could not listen"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return TcpListener(socket_fd, address);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto TcpListener::accept() -> Result<TcpConnection>
|
||||||
|
{
|
||||||
|
socklen_t size = sizeof(address);
|
||||||
|
|
||||||
|
int socket = ::accept(this->fd, (struct sockaddr*)&address, &size);
|
||||||
|
if (socket < 0) {
|
||||||
|
return std::unexpected(errno_shim("could not accept"));
|
||||||
|
}
|
||||||
|
return TcpConnection(*this, socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
38
backend/src/tcp.hpp
Normal file
38
backend/src/tcp.hpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <expected>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace mst {
|
||||||
|
template <typename T> using Result = std::expected<T, std::string>;
|
||||||
|
|
||||||
|
class TcpListener;
|
||||||
|
|
||||||
|
class TcpConnection {
|
||||||
|
public:
|
||||||
|
auto write(uint8_t* buffer, size_t len) -> Result<size_t>;
|
||||||
|
auto read(uint8_t* buffer, size_t len) -> Result<size_t>;
|
||||||
|
TcpConnection(TcpListener&, int fd)
|
||||||
|
: fd(fd) { };
|
||||||
|
|
||||||
|
private:
|
||||||
|
int fd;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TcpListener {
|
||||||
|
|
||||||
|
public:
|
||||||
|
static auto bind(const std::string& host, uint16_t port)
|
||||||
|
-> Result<TcpListener>;
|
||||||
|
auto accept() -> Result<TcpConnection>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TcpListener(int fd, sockaddr_in address)
|
||||||
|
: fd(fd)
|
||||||
|
, address(address) { };
|
||||||
|
int fd;
|
||||||
|
sockaddr_in address;
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user