Exemple #1
0
void Record::write(Buffer * buffer) {
  label->write(buffer);
  buffer->writeUInt16(type);
  buffer->writeUInt16(IN_CLASS);
  buffer->writeUInt32(ttl);
  writeSpecific(buffer);
}
// NOTICE: This method call blocks
// virtual
void SocketServer::run(int numMessagesToRead /*default 0*/)
{
  int numMessagesRead = 0;
  fd_set socketFdReadSet, socketFdWriteSet, socketFdErrorSet;
  int nready;
  char msgBuffer[MAX_MESSAGE_LENGTH];

  // perform anything the SocketServer Implementations may
  // need to do before starting the loop, like a TCP accept
  if(!runSpecific())
  {
    return;
  }

  FD_ZERO(&socketFdReadSet);
  FD_ZERO(&socketFdWriteSet);
  FD_ZERO(&socketFdErrorSet);

  while((numMessagesToRead == 0 || numMessagesRead < numMessagesToRead) && runServer_)
  {

    // We could be more extensable by having a list of handlers and iterate it

    // The handler/socket is only readable or writable, not both
    if(handler_->isReadable())
    {
      FD_SET(sockFd_, &socketFdReadSet);
      FD_ZERO(&socketFdWriteSet);
    }
    else
    {
      FD_SET(sockFd_, &socketFdWriteSet);
      FD_ZERO(&socketFdReadSet);
    }

    // Always check for errors
    FD_SET(sockFd_, &socketFdErrorSet);

    // This call blocks
    if((nready = select(sockFd_+1, &socketFdReadSet, &socketFdWriteSet, &socketFdErrorSet, tval_)) < 0)
    {
      std::cerr << "Error in select";
    }

    if(nready == 0 && tval_ != NULL)
    {
      handler_->handleTimeout();
      // tval_ is reset to the number of seconds not slept
      tval_->tv_sec  = timeout_sec_;
      tval_->tv_usec = timeout_usec_;
      numMessagesRead++;
    }

    // Socket is ready to read
    if(FD_ISSET(sockFd_, &socketFdReadSet))
    {
      int numBytesRead = readSpecific(msgBuffer);
      numMessagesRead++;

      if(isDebug())
      {
        std::cout << "Received a message of size: " << numBytesRead;
      }

      handler_->handleMessage(msgBuffer, numBytesRead, &clientAddress_);
    }

    // Socket is ready to write
    if(FD_ISSET(sockFd_, &socketFdWriteSet))
    {
      int numBytesWritten = writeSpecific(handler_->getMessage(), handler_->getMessageLength());

      if(isDebug())
      {
        std::cout << "Replied with a message of size: " << numBytesWritten;
      }
    }

    // Socket has an error
    if(FD_ISSET(sockFd_, &socketFdErrorSet))
    {
      // TODO should we pass this to the handler too?

      std::cerr << "Error on socket";
      close(sockFd_);
      sockFd_ = -1;
    }
  }
}