void KeyValueStore::InternalThread::incomingRoutine() { const Config::ServerInformation& info = config.getServerInformation(); Config::ThreadControl& control = config.getThreadControl(); Mutex& inMutex = control.getInMutex(); Condition& cond = control.getInCondition(); Thread incoming; Incoming inTask; int currId = -1; static bool first = true; // Init connection info SocketAddress sock(info.address, info.internalPort); ServerSocket server; try { server.bind(sock, true); server.listen(5); } catch(Exception& e) { printKv("Could not initialize internal thread, please restart server ("<< e.displayText()<< ")"); } StreamSocket client; while(control.isLive()) { inMutex.lock(); cond.wait(inMutex); unsigned nextId = control.getConnectedId(); inMutex.unlock(); // NOTE: From a security perspective this is not safe. // if someone tries to connect at the same time a rejoin // was initiated, they could easily perform a MITM attack. // However, since this is an academic exercise, I am not too // concerned with security (as can be seen by many other components // in this system as well). if(currId != (int)nextId) { currId = nextId; // TODO: Update processing thread somehow printKv("Told a new server should be connecting..."); try { client = server.acceptConnection(); printKv("Incoming server connected: "<< currId); inTask.cancel(); if(!first) incoming.join(); first = false; inTask = Incoming(client, &config.getThreadControl()); incoming.start(inTask); printKv("Handling new server"); } catch(TimeoutException& e) { printKv("Server did not connect in time - we don't want the system to be hung up, though ("<< e.displayText() <<")"); } } } server.close(); }
void SocketTest::testAddress() { ServerSocket serv; serv.bind(SocketAddress()); serv.listen(); StreamSocket ss; ss.connect(SocketAddress("localhost", serv.address().port())); StreamSocket css = serv.acceptConnection(); assert (css.peerAddress().host() == ss.address().host()); assert (css.peerAddress().port() == ss.address().port()); }
int main(int argc, const char * argv[]) { ServerSocket mainSocket = ServerSocket(4444); Socket socket = mainSocket.acceptConnection(); socket.beginHandling(); socket.closeSocket(); mainSocket.close(); return 0; }
void LocalSocketTest::testAddress() { SocketAddress sas("/tmp/poco.server.tcp.sock"); ServerSocket serv; serv.bind(sas); serv.listen(); StreamSocket ss; SocketAddress sac("/tmp/poco.client.tcp.sock"); ss.connect(sas, &sac); StreamSocket css = serv.acceptConnection(); assert (css.peerAddress().host() == ss.address().host()); assert (css.peerAddress().port() == ss.address().port()); }
/** Public thread methods (clients connect here) */ void KeyValueStore::PublicThread::run() { Thread threads[MAX_CLIENT_THREADS]; HandleClient threadInst[MAX_CLIENT_THREADS]; const Config::ServerInformation& info = config.getServerInformation(); Config::ThreadControl& control = config.getThreadControl(); int id = 0; char full = Protocol::SRV_FULL; char conn = Protocol::SRV_CONN; ServerSocket server; SocketAddress sock(info.address, info.pubPort); server.bind(sock, true); server.listen(5); printKv("Listening for clients on "<< info.address <<":"<< info.pubPort); while(control.isLive()) { // Simply do thread per client StreamSocket client = server.acceptConnection(); printKv("Received client connection request - waiting for thread to free up"); // Wait five seconds try { freeThreads.wait(5000); // This beats busy waiting } catch(TimeoutException& notUsed(e)) { printKv("Server full - closing connection to client"); client.sendBytes(&full, sizeof(full)); client.close(); continue; } // Send success client.sendBytes(&conn, sizeof(conn)); // tryJoin() doesn't work properly in linux, using isRunning() instead // actively search for the next available thread while(threads[id].isRunning()){ // Try to get an available thread id = (id + 1) % MAX_CLIENT_THREADS; Thread::sleep(250); // 250ms between each check } printKv("Serving client"); threadInst[id] = HandleClient(client, control); threads[id].start(threadInst[id]); } server.close(); freeThreads.set(); // Free a thread with semaphore }