void DataSink::_ReadCallback(ev::io &watcher, int revents) { if (EV_ERROR & revents) { LOG(WARNING) << "got invalid event"; return; } ByteBuffer *buf = (ByteBuffer *) watcher.data; buf->Defragment(); int len = buf->GetContinuousBytesLeft(); unsigned int numBytesReceived = recv(watcher.fd, buf->GetWriteReference(), len, MSG_NOSIGNAL); buf->BytesWritten(numBytesReceived); if (numBytesReceived < 0) { LOG(ERROR) << "failed reading socket - client probably disconnected"; return; } if (numBytesReceived <= 0) { // Stop and free watcher if client socket is closing LOG(INFO) << "client disconnected: " << _watcherMap[&watcher] << " -> " << --_numConnectedClients << " client(s) connected"; _DeleteAndCleanupWatcher(watcher); return; } while (buf->GetBytesAvailable() > 4) { // As long as there are more than 4 bytes available there could be // (at least) one more full message in the buffer int messageLength = ntohl(*((unsigned int *) buf->GetReadReference())); if (messageLength > buf->GetCapacity() - 4) { // Current buffer too small, double the capacity at a minimum // and wait until next read on socket if (messageLength > buf->GetCapacity() * 2) buf->Resize(messageLength); else buf->Resize(buf->GetCapacity() * 2); LOG(INFO) << "Buffer resized, new capacity: " << buf->GetCapacity(); break; } if (buf->GetBytesAvailable() - 4 < messageLength) // Fragmented packet, wait until next event. // Note that the same message length header will be read over again break; // There is still at least one more full message available buf->BytesRead(4); _router->Route(buf->GetReadReference(), messageLength); buf->BytesRead(messageLength); } _ioLogger->Read(numBytesReceived); }
// tool functions bool TextHandler::read_file(const string & file_path, ByteBuffer & data) { int length = 0; ifstream file(file_path.c_str(), ios::binary); if(false == file.good()) { cerr << "Read txt result file failed, path = " << file_path << endl; return false; } file.seekg (0, ios::end); length = file.tellg(); file.seekg (0, ios::beg); data.Resize(length); file.read(data.GetPtr(), length); file.close(); return true; }