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; } } }