/** * prüft auf neue Clients. * * @author FloSoft */ bool LobbyServer::CheckForNewClients() { SocketSet set; set.Add(serverSock_); if( set.Select(0, 0) > 0) { if(set.InSet(serverSock_)) { Socket client = serverSock_.Accept(); if(!client.isValid()) return false; unsigned playerid = static_cast<unsigned>(players.size()); while(players.find(playerid) != players.end()) ++playerid; LOG.write("New client connected from %s\n") % client.GetPeerIP(); LobbyPlayer p; p.attach(client, playerid); players[playerid] = p; LOG.write("Player-ID %d\n") % playerid; p.Send(new LobbyMessage_Id(playerid), true); } } return true; }
/** * Hauptschleife. * * @author FloSoft */ void LobbyClient::Run(void) { if(state == CS_STOPPED) return; SocketSet set; // erstmal auf Daten überprüfen set.Clear(); // zum set hinzufügen set.Add(socket); if(set.Select(0, 0) > 0) { // nachricht empfangen if(!recv_queue.recv(socket)) { LOG.lprintf("Receiving Message from server failed\n"); ServerLost(); return; } } // nun auf Fehler prüfen set.Clear(); // zum set hinzufügen set.Add(socket); // auf fehler prüfen if(set.Select(0, 2) > 0) { if(set.InSet(socket)) { // Server ist weg LOG.lprintf("Error on socket to server\n"); ServerLost(); return; } } // maximal 10 Pakete verschicken if(!send_queue.send(socket, 10)) { ServerLost(); return; } // recv-queue abarbeiten while(recv_queue.count() > 0) { recv_queue.front()->run(this, 0xFFFFFFFF); recv_queue.pop(); } }
/** * * * @author FloSoft */ Message* Message::recv(Socket& sock, int& error, bool wait, Message * (*createfunction)(unsigned short)) { error = -1; unser_time_t time = TIME.CurrentTick(); unser_time_t timeout = time; unsigned int received; SocketSet set; while(true) { // Warten wir schon 5s auf Antwort? if(time - timeout > 15000) wait = false; time = TIME.CurrentTick(); // SocketSet "saubermachen" set.Clear(); // Socket hinzufgen set.Add(sock); // liegen Daten an? int retval = set.Select(0, 0); if(retval <= 0) { if(wait) continue; if(retval != -1) error = 0; return NULL; } // liegen diese Daten an unserem Socket, bzw wieviele Bytes liegen an? if(!set.InSet(sock) || sock.BytesWaiting(&received) != 0) { if(wait) continue; error = 1; return NULL; } // socket ist geschlossen worden if(received == 0) return NULL; // haben wir schon eine vollständige nachricht? (kleinste nachricht: 6 bytes) if(received < 6) { if(wait) continue; error = 2; return NULL; } break; } int read = -1; char block[6]; unsigned short* id = (unsigned short*)&block[0]; unsigned int* length = (unsigned int*)&block[2]; // block empfangen read = sock.Recv(block, 6, false); if(read != 6) { LOG.write("recv: block: only got %d bytes instead of %d, waiting for next try\n", read, 6); if(read != -1) error = 3; return NULL; } read = sock.BytesWaiting(); static unsigned int blocktimeout = 0; if(read < (signed)((*length) + 6) ) { ++blocktimeout; LOG.write("recv: block-waiting: not enough input (%d/%d) for message (0x%04X), waiting for next try\n", read, (*length) + 6, *id); if(blocktimeout < 120 && read != -1) error = 4; return NULL; } blocktimeout = 0; // Block nochmals abrufen (um ihn aus dem Cache zu entfernen) read = sock.Recv(block, 6); if(read != 6) { LOG.lprintf("recv: id,length: only got %d bytes instead of %d\n", read, 2); return NULL; } Message* msg = createfunction(*id); if(!msg) return NULL; // Daten abrufen msg->recv(sock, *length); return msg; }