20 int flags = fcntl(socket, F_GETFL, 0);
24 return fcntl(socket, F_SETFL, flags | O_NONBLOCK) != -1;
38 if (setsockopt(
m_serverSocket, SOL_SOCKET, SO_REUSEADDR, &opt,
sizeof(opt)) < 0) {
50 struct sockaddr_in addr;
51 std::memset(&addr, 0,
sizeof(addr));
52 addr.sin_family = AF_INET;
53 addr.sin_addr.s_addr = INADDR_ANY;
54 addr.sin_port = htons(port);
56 if (bind(
m_serverSocket,
reinterpret_cast<struct sockaddr *
>(&addr),
sizeof(addr)) < 0) {
97 struct sockaddr_in clientAddr;
98 socklen_t addrLen =
sizeof(clientAddr);
100 int newSocket = accept(
m_serverSocket,
reinterpret_cast<struct sockaddr *
>(&clientAddr), &addrLen);
116 char addrStr[INET_ADDRSTRLEN];
117 inet_ntop(AF_INET, &clientAddr.sin_addr, addrStr, INET_ADDRSTRLEN);
118 m_clientAddress = std::string(addrStr) +
":" + std::to_string(ntohs(clientAddr.sin_port));
130 uint8_t tempBuffer[65536];
132 ssize_t bytesRead = recv(
m_clientSocket, tempBuffer,
sizeof(tempBuffer), 0);
135 if (errno == EAGAIN || errno == EWOULDBLOCK) {
142 if (bytesRead == 0) {
151 uint32_t payloadLength = 0;
191 struct timeval timeout;
195 int activity = select(maxFd + 1, &readFds,
nullptr,
nullptr, &timeout);
214 std::vector<uint8_t> data = frame.
ToBytes();
215 size_t totalSent = 0;
217 while (totalSent < data.size()) {
218 ssize_t sent = send(
m_clientSocket, data.data() + totalSent, data.size() - totalSent, MSG_NOSIGNAL);
220 if (errno == EAGAIN || errno == EWOULDBLOCK) {
226 totalSent +=
static_cast<size_t>(sent);
ConnectCallback m_connectCallback
void Stop()
Stops the server and disconnects any client.
bool Send(const Network::MessageFrame &frame)
Sends a message frame to the connected client. Returns true on success.
bool Start(uint16_t port)
Starts the server listening on the given port. Returns true on success.
DisconnectCallback m_disconnectCallback
void DisconnectClient()
Disconnects the current client without stopping the server.
std::vector< uint8_t > m_recvBuffer
bool IsClientConnected() const
Returns true if a client is currently connected.
bool IsRunning() const
Returns true if the server is listening.
std::string m_clientAddress
void Poll()
Processes pending I/O (accept, read). Call periodically from the main loop.
MessageCallback m_messageCallback
bool SetNonBlocking(int socket)
constexpr size_t FRAME_HEADER_SIZE
static MessageFrame FromBytes(const uint8_t *data, size_t dataSize)
static bool ParseHeader(const uint8_t *data, size_t dataSize, uint32_t &outLength, Protocol::MessageType &outType)
std::vector< uint8_t > ToBytes() const