ACE之旅的開始問題

                             ACE之旅的開始問題
    最近閒來,沒什麼事情做,就來研究ACE。剛開始,接觸ACE遇到一些莫名其妙的問題。
以下是我碰到的問題,以及解決方法:
問題一:調用ACE::select(int,ACE_Handle_Set) 返回-1。
調 ACE_ERROR_RETURN((LM_DEBUG,"%p/n","ACE::select:"),-1);
輸出:app version not supported by dll.
剛開始一看到這個輸出,我一直都找不到問題的所在。一直在網上搜索問題的解決方法,發郵件給steve尋求解決方法。
他給我的回覆:he second issue could be that you're using a version of Windows or Winsock that's too old or            your  ACE configuration is not correct.
       對於他的回覆,我感覺一霧水,後來去看源代碼。
       發現app version not supported by dll 的錯誤是 WSAEMFILE。
     而這個錯誤WSAEMFILE在msdn上的描述:Invalid argument.
    Some invalid argument was supplied (for example, specifying an invalid level to the setsockopt function).     In some instances, it also refers to the current state of the socket—for instance, calling accept on a        socket that is not listening 。
     後來我才發現,我再調ACE::select之前,ACE_Handle_Set 對象裏面沒有句柄。
我提這個問題的一個提示:
在遇到莫名其妙的問題時候,先檢查自己的代碼是否有問題!
很多時候,我們一看到莫名其妙的問題時候,心理就發毛,一直尋找答案。
2:第二個問題:在ACE 提供的例子C++NPv1_Reactive_Logging_Server_Ex_vc8.vcproj中的代碼:
virtual int handle_connections () { ACE_SOCK_Stream logging_peer; while (acceptor ().accept (logging_peer) != -1) { ACE_FILE_IO *log_file = new ACE_FILE_IO; // Use the client's hostname as the logfile name. make_log_file (*log_file, &logging_peer); // Add the new <logging_peer>'s handle to the map and // to the set of handles we <select> for input. log_map_.bind (logging_peer.get_handle (), log_file); master_handle_set_.set_bit (logging_peer.get_handle ()); } active_read_handles_.clr_bit (acceptor ().get_handle ()); return 0; } virtual int handle_data (ACE_SOCK_Stream *) { ACE_Handle_Set_Iterator peer_iterator (active_read_handles_); for (ACE_HANDLE handle; (handle = peer_iterator ()) != ACE_INVALID_HANDLE; ) { ACE_FILE_IO *log_file = 0; log_map_.find (handle, log_file); Logging_Handler logging_handler (*log_file, handle); if (logging_handler.log_record () == -1) { logging_handler.close (); master_handle_set_.clr_bit (handle); log_map_.unbind (handle); log_file->close (); delete log_file; } } return 0; }
程序運行到handle_data有時候會崩潰,原因如果當前handle 是監聽的那個句柄。這時log_file 還是爲0.
因此對log_file進行訪問,會使程序崩潰。
解決方法在Logging_Handler logging_handler (*log_file, handle)之前加:
if(log_file == 0)
continue;
3:在該例子中的函數:
int Logging_Handler::write_log_record (ACE_Message_Block *mblk) { // Peer hostname is in the <mblk> and the log record data // is in its continuation. if (log_file_.send_n (mblk) == -1) return -1; if (ACE::debug ()) { // Build a CDR stream from the log record data. ACE_InputCDR cdr (mblk->cont ()); ACE_CDR::Boolean byte_order; ACE_CDR::ULong length; // Extract the byte-order and length, ending up at the start // of the log record itself. Use the byte order to properly // set the CDR stream for extracting the contents. cdr >> ACE_InputCDR::to_boolean (byte_order); cdr.reset_byte_order (byte_order); cdr >> length; ACE_Log_Record log_record; cdr >> log_record; // Finally extract the <ACE_log_record>. log_record.print (mblk->rd_ptr (), 1, cerr); } return mblk->total_length (); }
輸出到文件的內容有亂碼,一個簡單的解析方法:
 int Logging_Handler::write_log_record(ACE_Message_Block* mblk) { std::ostringstream os; ACE_InputCDR cdr(mblk->cont()); ACE_CDR::Boolean byte_order; cdr >> ACE_InputCDR::to_boolean(byte_order); cdr.reset_byte_order(byte_order); ACE_CDR::ULong length; cdr >> length; ACE_Log_Record log_record; cdr >> log_record; log_record.print(mblk->rd_ptr(),1,os); os<<"/n"; _log_file.send(os.str().c_str(),os.str().length()); std::cout<<os.str()<<std::endl; return mblk->total_length(); }

4:調ACE_ERROR_RETURN((LM_DEBUG,"%s%p/n","The error is "),-1)有時程序會崩潰,有時不會。
如果在崩潰的時候,去掉%s,就不會崩潰。
但是調式,會在output.c的一個地方出現訪問衝突。
在查看ACE_Log_Msg::log()方法介紹,其介紹const ACE_TCHAR* format_str跟printf類似。但沒看到不能如例子所舉的那樣用法。

以上是我開始ACE之旅遇到的問題,及解決方法。
 
發佈了49 篇原創文章 · 獲贊 24 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章