diff options
author | Jonas Smedegaard <dr@jones.dk> | 2017-06-24 09:21:37 +0200 |
---|---|---|
committer | Jonas Smedegaard <dr@jones.dk> | 2017-06-24 09:21:37 +0200 |
commit | 3d39f109ba8ea7ae9778c58bd1665b9e8e0f45cb (patch) | |
tree | 9a5684babcd16d302fbe59c56b6045660ad62488 /src/network/tcp_server_socket.hpp | |
parent | f9cee98aacd6aea8ccb7f5677b4ff1e1e234e4d1 (diff) | |
parent | c21cbbf9667991d2b928562a9c199e625d3f9bba (diff) | |
download | biboumi-3d39f109ba8ea7ae9778c58bd1665b9e8e0f45cb.tar.gz biboumi-3d39f109ba8ea7ae9778c58bd1665b9e8e0f45cb.tar.bz2 biboumi-3d39f109ba8ea7ae9778c58bd1665b9e8e0f45cb.tar.xz biboumi-3d39f109ba8ea7ae9778c58bd1665b9e8e0f45cb.zip |
Updated version 5.0 from 'upstream/5.0'
with Debian dir 2ae31d03ffb1d79153a692af23c7b2b097cc4b2b
Diffstat (limited to 'src/network/tcp_server_socket.hpp')
-rw-r--r-- | src/network/tcp_server_socket.hpp | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/network/tcp_server_socket.hpp b/src/network/tcp_server_socket.hpp new file mode 100644 index 0000000..652b773 --- /dev/null +++ b/src/network/tcp_server_socket.hpp @@ -0,0 +1,69 @@ +#pragma once + +#include <network/socket_handler.hpp> +#include <network/poller.hpp> +#include <logger/logger.hpp> + +#include <string> + +#include <arpa/inet.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/ip.h> + +#include <cstring> + +template <typename RemoteSocketType> +class TcpSocketServer: public SocketHandler +{ + public: + TcpSocketServer(std::shared_ptr<Poller>& poller, const uint16_t port): + SocketHandler(poller, -1) + { + if ((this->socket = ::socket(AF_INET6, SOCK_STREAM, 0)) == -1) + throw std::runtime_error(std::string{"Could not create socket: "} + std::strerror(errno)); + + int opt = 1; + if (::setsockopt(this->socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) + throw std::runtime_error(std::string{"Failed to set socket option: "} + std::strerror(errno)); + + struct sockaddr_in6 addr{}; + addr.sin6_family = AF_INET6; + addr.sin6_port = htons(port); + addr.sin6_addr = IN6ADDR_ANY_INIT; + if ((::bind(this->socket, (const struct sockaddr*)&addr, sizeof(addr))) == -1) + { // If we can’t listen on this port, we just give up, but this is not fatal. + log_warning("Failed to bind on port ", std::to_string(port), ": ", std::strerror(errno)); + return; + } + + if ((::listen(this->socket, 10)) == -1) + throw std::runtime_error("listen() failed"); + + this->accept(); + } + ~TcpSocketServer() = default; + + void on_recv() override + { + // Accept a RemoteSocketType + int socket = ::accept(this->socket, nullptr, nullptr); + + auto client = std::make_unique<RemoteSocketType>(poller, socket, *this); + this->poller->add_socket_handler(client.get()); + this->sockets.push_back(std::move(client)); + } + + protected: + std::vector<std::unique_ptr<RemoteSocketType>> sockets; + + private: + void accept() + { + this->poller->add_socket_handler(this); + } + bool is_connected() const override + { + return true; + } +}; |