80 lines
1.9 KiB
C++
80 lines
1.9 KiB
C++
#include "TCPListener.h"
|
|
#include "TCPSocket.h"
|
|
#include "TCPClient.h"
|
|
#include "IListenerInterface.h"
|
|
|
|
#include "logging/Logger.h"
|
|
|
|
namespace Feather::Network
|
|
{
|
|
TCPListener::TCPListener(uint16_t port, IListenerInterface* callbacks)
|
|
: m_callbacks(callbacks)
|
|
{
|
|
// Setup the listen socket.
|
|
auto socket = std::make_unique<TCPSocket>();
|
|
|
|
if (!socket->IsValid())
|
|
{
|
|
Log::Error("Socket failed to be created.");
|
|
return;
|
|
}
|
|
|
|
if (!socket->MarkReusable())
|
|
{
|
|
Log::Error("Failed to mark socket as resuable.");
|
|
return;
|
|
}
|
|
|
|
if (socket->IsIPV6() && !socket->MarkDualBind())
|
|
{
|
|
Log::Error("Failed to mark IPv6 socket as dual-bind.");
|
|
return;
|
|
}
|
|
|
|
if (!socket->Bind(port))
|
|
{
|
|
Log::Error("Failed to bind socket to port {}.", port);
|
|
return;
|
|
}
|
|
|
|
if (!socket->MarkNonBlocking())
|
|
{
|
|
Log::Error("Failed to mark socket as non-blocking.");
|
|
return;
|
|
}
|
|
|
|
auto ListenerCallback = [](evconnlistener* evListener, SocketHandle socket, sockaddr* addr, int len, void* self)
|
|
{
|
|
TCPListener* listener = static_cast<TCPListener*>(self);
|
|
listener->OnClientConnect(std::make_unique<TCPClient>(listener, socket, addr));
|
|
};
|
|
|
|
if (!socket->Listen(ListenerCallback, this))
|
|
{
|
|
Log::Error("Failed to start listening on socket.");
|
|
return;
|
|
}
|
|
|
|
m_socket = std::move(socket);
|
|
}
|
|
|
|
TCPListener::~TCPListener()
|
|
{
|
|
}
|
|
|
|
bool TCPListener::IsValid() const
|
|
{
|
|
return m_socket != nullptr;
|
|
}
|
|
|
|
void TCPListener::OnClientConnect(TCPClientHandle&& client)
|
|
{
|
|
m_callbacks->OnClientConnect(std::move(client));
|
|
}
|
|
|
|
void TCPListener::OnClientDisconnected(const TCPClient* client)
|
|
{
|
|
m_callbacks->OnClientDisconnect(client);
|
|
}
|
|
}
|