Exemple #1
0
void NetworkThread::ReceiveActions()
{
  char* buffer;
  size_t packet_size;
  Network* net = Network::GetInstance();
  std::list<DistantComputer*>::iterator dst_cpu;
  std::list<DistantComputer*>& cpu = net->GetRemoteHosts();

  // While the connection is up
  while (Continue()) {
    if (net->GetState() == WNet::NETWORK_PLAYING && cpu.empty()) {
      // If while playing everybody disconnected, just quit
      break;
    }

    //Loop while nothing is received
    while (Continue()) {
      IndexServer::GetInstance()->Refresh();

      // Check forced disconnections
      dst_cpu = cpu.begin();
      while (Continue() && dst_cpu != cpu.end()) {
        // Disconnection is in 2 phases to be handled by one thread
        if ((*dst_cpu)->MustBeDisconnected()) {
          net->CloseConnection(dst_cpu);
          dst_cpu = cpu.begin();
        }
        else
          dst_cpu++;
      }

      // List is now maybe empty
      if (cpu.empty() && net->IsClient()) {
        fprintf(stderr, "you are alone!\n");
        Stop();
        return; // We really don't need to go through the loops
      }

      net->WaitActionSleep();

      int num_ready = net->CheckActivity(100);
      // Means something is available
      if (num_ready>0)
        break;
      // Means an error
      else if (num_ready == -1) {
        //Spams a lot under windows without the errno check...
        fprintf(stderr, "SDLNet_CheckSockets: %s\n", SDLNet_GetError());

        continue; //Or break?
      }
    }

    for (dst_cpu = cpu.begin();
         Continue() && dst_cpu != cpu.end();
         dst_cpu++) {
      // Check if this socket contains data to receive
      if ((*dst_cpu)->SocketReady()) {

        if (!(*dst_cpu)->ReceiveData(&buffer, &packet_size)) {
          // An error occured during the reception
          (*dst_cpu)->ForceDisconnection();
          continue;
        }

        if (!buffer && !packet_size) {
          // Client is valid but there is not yet enough data to read an action
          continue;
        }

#ifdef LOG_NETWORK
        if (fin != 0) {
          int tmp = 0xFFFFFFFF;
          write(fin, &packet_size, 4);
          write(fin, buffer, packet_size);
          write(fin, &tmp, 4);
        }
#endif

        Action* a = new Action(buffer, (*dst_cpu));
        free(buffer);

        MSG_DEBUG("network.traffic", "Received action %s",
                  ActionHandler::GetActionName(a->GetType()).c_str());
        net->HandleAction(a, *dst_cpu);
      }
    }
  }
}