// This demonstrates how to perform a graceful disconnect, where data sending/receiving // is allowed to complete before the client is disconnected. // In this demo the server begins the graceful disconnect process // It is also possible for a client to initiate a graceful disconnect #include #include #include #include using namespace std; // Entry point void main() { // Setup server int iReturn = 0; cout << "DarkNet version: " << mnGetVersion() << "\n"; long long int RecvPacket = mnCreatePacket(); long long int SendPacket = mnCreatePacket(); mnSetMemorySize(SendPacket,1024); mnSetUsedSize(SendPacket,1024); mnStart(1,0); mnDisableUDP(0); mnSetLocal(0,"127.0.0.1",6565,0,0); mnEnableGracefulDisconnect(0); // Enable graceful disconnect mnStartServer(0,50,0,0); cout << "Server started on TCP port " << mnGetLocalPortTCP(0) << '\n'; // Send data to clients every SendFreq ms unsigned int SendTimer = 0; unsigned int SendFreq = 100; // Disconnect a client every DisconnectFreq ms unsigned int DisconnectTimer = 0; unsigned int DisconnectFreq = 3000; // Main loop bool bRunning = true; while(bRunning == true) { // Use less CPU Sleep(1); // Graceful close for(int cl = 1;cl<=mnGetMaxClients(0);cl++) { int iClientStatus = mnClientConnected(0,cl); switch(iClientStatus) { // Shutdown client // Further send operations to this client will fail silently // mnClientConnected will now return 2 case(C_CONNECTED): if(clock()-DisconnectTimer > DisconnectFreq) { mnShutdownClient(0,cl); cout << "Shut down client " << cl << "\n"; DisconnectTimer = clock(); } break; // Client is sending us data still // We will wait forever, but a robust server should // only wait for a set amount of time, and forcefully // disconnect clients that take too long case(C_NO_SEND): // Nothing to do while we wait break; // Client has finished sending us data // We must get it from packet queue // Once packet queue is empty, client // will be disconnected by mnClientConnected // and mnClientConnected will return 0 case(C_NO_SEND_RECV): cout << "mnClientConnected (" << cl << "): " << iClientStatus << "\n"; while(mnRecvTCP(0,RecvPacket,cl) > 0) { char * str = mnGetStringC(RecvPacket,0,true); cout << "Final string received from client " << cl << ": " << str; } break; } } // New clients iReturn = mnClientJoined(0); if(iReturn > 0) { cout << "New client joined, ID: " << iReturn << "\n"; DisconnectTimer = clock(); } // Leaving clients iReturn = mnClientLeft(0); if(iReturn > 0) { cout << "Client left, ID: " << iReturn << "\n"; } // Receive data for(int cl = 1;cl<=mnGetMaxClients(0);cl++) { if(mnClientConnected(0,cl) == C_CONNECTED) { // TCP packets iReturn = mnRecvTCP(0,RecvPacket,cl); if(iReturn > 0) { char * str = mnGetStringC(RecvPacket,0,true); cout << "String received from client " << cl << ": " << str; } } } // Send data if(clock() - SendTimer > SendFreq) { for(int n = 1;n<=mnGetMaxClients(0);n++) { if(mnClientConnected(0,n) == C_CONNECTED) { mnSendTCP(0,SendPacket,n,true,true); cout << "Packet sent\n"; } } SendTimer = clock(); } } }