簡體   English   中英

使用boost :: asio的分段錯誤,帶有截止時間的異步udp服務器

[英]Segmentation fault with boost::asio, asynchronous udp-server with deadline_timer

我在使用boost :: asio庫的服務器程序時遇到了麻煩。

Server類非常類似於boost asio教程“異步udp服務器”中介紹的類。

該類具有一個公共方法(“ sendMessageTo”),該公共方法由消息-處理器對象調用,如果該方法由Duration_timer線程調用,則會發生分段錯誤。 它通過調用新的std :: string(msg,len)發生,這讓我感到困惑。 msg包含應包含的內容,len也包含。

void Server::sendMessageTo(const char* msg, size_t len, udp::endpoint to)
{
    boost::shared_ptr<std::string> message( new std::string (msg,len) );
    socket.async_send_to(boost::asio::buffer(*message), to,
                         boost::bind(&Server::handleSend, this, message,
                                     boost::asio::placeholders::error,
                                     boost::asio::placeholders::bytes_transferred));
}

第一次嘗試調用方法“ sendMessageTo”時,一切正常:稍后在同一線程中調用,該線程由服務器類的“ handleReceive”方法打開。

我的消息處理器對象是某種狀態機,它保留遠程端點,並且在某些狀態下定期希望將一些udp消息發送回端點。 因此,使用了一個asio :: deadline_timer。 截止時間計時器是使用相同的io_service創建的,udp服務器在其上運行。 首次取消計時器時,message_processor對象內的state_handling方法將調用“ sendMessageTo”方法,從而發生分段錯誤。 “ sendMessageTo”的所有參數均有效,並包含期望值。

我的消息處理器類的構造函數頭(稱為Transaction)

Transaction::Transaction(ClientReference *cli, ServerReference *serv)
    : timer(*(serv->getIOService()), boost::posix_time::milliseconds(TRANSACTION_THREAD_SLEEP_MILLISEC)),
      clientEndpoint(serv->getEndpoint())

timer是asio :: deadline_timer對象,clientEndpoint是udp :: endpoint

服務器響應在方法Transaction :: runThread()中發送

server->sendMessageTo(&encryptedMsgBuf[0], size, clientEndpoint);

cryptoMsgBuf是一個char數組緩沖區,用於存儲加密的消息,並且是Transaction-對象的一部分。

在方法Transaction :: runThread()的末尾,將delay_timer調用到方法runThread()上以重新激活它,直到達到最終狀態:

if (state != done && state != expired) 
    timer.async_wait(boost::bind(&Transaction::runThread, this));

謝謝你的幫助。

我不確定這件事是100%肯定的,因為我無法從您發布的內容中本地重現您的錯誤,但是我強烈懷疑您的問題是由於消息字符串變量的作用域所致。 我過去在boost::shared_ptr遇到過一些問題,其中shared_ptr破壞早於預期。 如果是這種情況,則在對Server::sendMessageTo()的調用結束時, shared_ptr message可能會被破壞,並且當異步傳輸實際上嘗試開始時,該內存已被釋放,從而導致段錯誤。

總的來說,我希望將實際上從我接收和接收到的緩沖區作為服務器和客戶端類的私有成員,以確保它們是靜態范圍的,並且不會在發送或接收過程中途意外消失。 它可能會占用一些內存,但是我發現它讓我省心了。 如果這種方法不能給您帶來任何快樂,請告訴我,我將看看是否可以在本地重現該錯誤。 (目前,我的“本地復制”嘗試包括我破解了一個舊的“使用ASIO的服務器-客戶端”示例以如上所述分配分配TX緩沖區,然后浪費了一些內存,因此如果TX試圖做進一步的工作堆訪問它應該是段錯誤的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM