async_read_some を使用して、_data という char[] に保存されているポートからデータを読み取ります。そのバッファ サイズは、すべてのリクエストに対して十分な大きさです。
void start() {
socket_.async_read_some(boost::asio::buffer(data_,BUFFERSIZE),make_custom_alloc_handler(allocator_,boost::bind(&attentionSession::handle_read, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)));
}
void handle_read(const boost::system::error_code& error, size_t bytes_transferred) {
string ip = socket_.remote_endpoint().address().to_string();
log->processData(data_,ip,"memory");
strcpy(data_,"");
}
processData は、新しく割り当てられた別の char* にコピーすることで、リクエストにいくつかの追加情報 (タイムスタンプなど) を追加します。次に、この char[] が writeToMemory(char*) に送信され、その char* が std::string memoryBuffer に追加されます。
void writeCacheToFile() {
// This function writes buffer data to the log file
char* temp = new char[memoryBuffer.length() + 1];
strcpy(temp, memoryBuffer.c_str());
writeToFile(temp);
delete[] temp;
memoryBuffer.clear();
}
void writeToMemory(char* data) {
int maxSize = 1024;
// Checks if char* data would 'fit' into the pre-defined maxSize
if ((strlen((const char*)data) + memoryBuffer.length()) >= maxSize) {
writeCacheToFile(); // If not the cache memoryBuffer is saved first
}
memoryBuffer.append((const char*) data);
cout << memoryBuffer.length() << endl;
}
それは機能しますが、常にリクエストがある場合(リクエストで攻撃する場合)、物事が台無しになります。上記の writeToMemory() 関数でわかるように、現在の memoryBuffer の長さを出力する行を追加します。これは、std::strings のスレッド セーフと関係があると思われる場所です。
96
188
284
3639
94
190
286
2591
102
198
294
388
484
2591
96
2591
96
190
286
2591
各 (processData() によって処理される) 要求の長さは 96 文字です。ただし、ここでは、memoryBuffer の長さが上下するだけです。一部の長さは、maxSize (1024 文字) よりもさらに大きくなります。
編集:サムは、さらにコードを追加する必要があると指摘しました。これは、io_service を開始する方法です。
boost::asio::io_service ioService;
boost::scoped_ptr<boost::thread> ioServiceThread;
server_class server (ioService,PORT); // Create server instance
ioServiceThread.reset (new boost::thread ( boost::bind ( &boost::asio::io_service::run, &ioService ) ) );
// Only one threaded io_service (to receive user inputs in main() function)
これは、リクエストを完了した後の async_acceptor の関数です。
typedef boost::shared_ptr<session_class> session_ptr;
void handleAccept(session_ptr thisSession, const boost::system::error_code& error) {
if (!error) {
thisSession->start(); // Calls the start() function above
thisSession.reset(new session(ioService,LOGGING_CLASS));
acceptor.async_accept(thisSession->socket(),boost::bind(&server_class::handleAccept, this, thisSession, PLACEHOLDER_ERROR));
}
}
session_class は、上記の関数 start() および handle_read(x,y) を保持します。LOGGING_CLASS は、ログ ファイルを書き込むためのクラスを提供します (関数 writeCacheToFile() および writeToMemory(char*) を保持します)。log (前述) は、このクラスの一種です。
EOE: 編集の終わり
boost::threads を使用してキャッシング部分 (受信した char* を std::string に追加) を外部委託して修正しようとすると、完全に混乱した memoryBuffer になります。
それは本当にstd::stringsのスレッドセーフか、それとも私が見逃した何かですか?
事前にご協力いただきありがとうございます。:)
ポール