50 lines
1.6 KiB
C++
50 lines
1.6 KiB
C++
/**
|
|
* To solve the problem of accept() blocking forever, we are going to use a classic networking trick:
|
|
* The Alarm Clock (select). Instead of letting accept() sleep forever, we set an alarm clock for 1 second.
|
|
* If a client calls before the alarm rings, we answer the phone (accept). If the alarm rings first, we wake up,
|
|
* check our "Stop Sign" (the interrupt flag), and if it's raised, we gracefully shut down.
|
|
*/
|
|
|
|
#ifndef IOVI_NETWORK_SERVER_SOCKET_THREAD_H
|
|
#define IOVI_NETWORK_SERVER_SOCKET_THREAD_H
|
|
|
|
#include "../NetworkConfig.h"
|
|
#include <string>
|
|
#include <thread>
|
|
#include <atomic> // For thread-safe "Stop Signs"
|
|
|
|
class ServerSocketThread {
|
|
SOCKET_TYPE serverSocket;
|
|
int port;
|
|
|
|
// THE STOP SIGN: std::atomic ensures that when one thread changes this
|
|
// to 'false', the other thread sees the change instantly, without caching issues.
|
|
std::atomic<bool> running{false};
|
|
|
|
// THE WORKER: The background thread that will run our server loop.
|
|
std::thread serverThread;
|
|
|
|
// The actual infinite loop that runs inside the background thread, main server logic
|
|
void serverLoop() const;
|
|
|
|
// The echo logic (same as before, but now static so the thread can call it)
|
|
static void handleClient(SOCKET_TYPE clientSocket);
|
|
|
|
public:
|
|
explicit ServerSocketThread(int p);
|
|
~ServerSocketThread();
|
|
|
|
// Starts the background thread
|
|
void start();
|
|
|
|
// Raises the stop sign and waits for the thread to finish cleanly
|
|
void stop();
|
|
|
|
// Checks if the server is currently running
|
|
bool isRunning() const {
|
|
return running.load();
|
|
}
|
|
};
|
|
|
|
#endif // IOVI_NETWORK_SERVER_SOCKET_THREAD_H
|