2012-02-16 26 views
1

我仍然在與IP攝像機通信的某種客戶端上工作。現在我有以下問題:Boost async_read不給我一個「幀結束」標誌

我向相機發送請求(特別是RTSP DESCRIBE)。現在,我得到它的答案,看起來像這樣:

RTSP/1.0 200 OK 
CSeq: 2 
Date: Thu, Jan 01 1970 00:31:41 GMT 
Content-Base: rtsp://192.168.0.42/mpeg4?mode=Live&stream=-1&buffer=0&seek=0&fps=100& metainfo=/ 
Content-Type: application/sdp 
Content-Length: 517 

這是答案的頭部,接着是所謂Session Description其在該領域Content-Length顯示的大小。實際上我並不在乎Session Description,我只是對Content-Base領域感興趣。但是,由於在同一個套接字上有一些通信,所以我需要刪除所有的數據。

用於接收來自boost::asioasync_read來電。 我的代碼如下(簡化的)是這樣的:由於通過一個空行其終止

CommandReadBuffer::CallbackFromAsyncWrite() 
{ 
boost::asio::async_read_until(*m_Socket, m_ReceiveBuffer,"\r\n\r\n", 
      boost::bind(&CommandReadBuffer::handle_rtsp_describe, this->shared_from_this(), 
        boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred)); 
} 

這一個至少讀取頭(如上所示)。像往常一樣async_write它只是讀取更多的數據,但從來沒有想過。現在,下一個回調函數:

void CommandReadBuffer::handle_rtsp_describe(const boost::system::error_code& err,size_t bytesTransferred) 
{ 
std::istream response_stream(&m_ReceiveBuffer); 
std::string header; 
// Just dump the data on the console 
while (std::getline(response_stream, header)) 
{ 
    // Normally I would search here for the desired content-base field 
    std::cout << header << "\n"; 
} 
boost::asio::async_read(*m_Socket, m_ReceiveBuffer, boost::asio::transfer_at_least(1), 
     boost::bind(&CommandReadBuffer::handle_rtsp_setup, this->shared_from_this(), 
          boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); 
} 

現在能正常工作,以及,如果我打印出接收的字節數,它總是215

現在,我們去到關鍵的回調:

void CommandReadBuffer::handle_rtsp_setup(const boost::system::error_code& err, size_t bytesTransferred) 
{ 
std::cout << "Error: " << err.message() << "\n"; 
    if (!err) 
    { 
     // Write all of the data that has been read so far. 
     std::cout << &m_ReceiveBuffer; 

    // Continue reading remaining data until EOF. 
    m_DeadlineTimer->async_wait(boost::bind(&CommandReadBuffer::handleTimeout, this->shared_from_this(),boost::asio::placeholders::error)); 
     boost::asio::async_read(*m_Socket, m_ReceiveBuffer, boost::asio::transfer_at_least(1), 
      boost::bind(&CommandReadBuffer::handle_rtsp_setup, this->shared_from_this(), 
           boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); 
} 
else if (err != boost::asio::error::eof) 
{ 
    std::cout << "Error: " << err.message() << "\n"; 
} 
else 
{ 
    std::cout << "End of Frame " << err.message() << "\n"; 
} 
} 

該部分讀取220個字節。如果我查看這個調用的console輸出,並將其與幀的實際有效負載進行比較(如Wireshark所示),我可以看到所有數據都已收到。現在我實際上會假設async_read會將我設爲eof錯誤。但是,error的返回碼是success,因此它再次調用async_read。這次沒有要接收的數據,也不會調用回調函數(因爲不會有更多的傳入數據)。

現在我實際上不知道如何才能確定所有數據都已發送。其實我會期待錯誤標誌被設置。

現在,這與異步HTTP客戶端的Boost示例的實現非常相似。在Example Boost Async HTTP Client中也是這樣做的。我在另一個調用中實現了這一點,並且它實際上工作。

現在我認爲它應該是沒有區別的async_read呼叫它是HTTP或RTSP - 幀的結尾是幀的結尾,如果沒有更多的數據要讀取。

我也知道,根據Boost文檔我使用

void async_read(
    AsyncReadStream & s, 
    basic_streambuf<Allocator> & b, 
    CompletionCondition completion_condition, 
    ReadHandler handler); 

這意味着該功能將一直持續到

The supplied buffer is full (that is, it has reached maximum size). 
The completion_condition function object returns 0. 

所以,如果沒有更多的數據閱讀,它只是繼續。 但我也試過重載函數沒有CompletionCondition參數,當錯誤發生時應該返回(EOF!) - 但是,這只是不會回調要麼...

有什麼建議?我只是不明白我在做什麼錯...

回答

3

我已經編寫了一個使用boost asio的RTSP客戶端和服務器庫,可以提供以下建議: RTSP消息語法是通用的:沒有必要用於不同的DESCRIBE和SETUP處理程序。一般而言

  • 寫的RTSP請求
  • 讀取響應做boost::asio::async_read_until("\r\n\r\n")
  • 然後檢查該Content-Length
  • 如果CONTENT_LENGTH> 0做boost::asio::transfer_at_least(content_length)

此外,爲什麼你期待EOF嗎?連接仍處於打開狀態:服務器正在等待另一個SETUP或PLAY請求,並且通常不會關閉連接,直到RTSP TCP連接超時爲止,根據RFC2326,該連接的默認值爲60秒。

如果在您的應用程序中,您已完成與RTSP服務器的交互,請在閱讀響應後關閉連接。

+0

與EOF的好處...我可能在我的腦海裏有什麼錯誤!那麼我確實向你告訴我的方向走了。但在這一點上有一個問題:當我收到對SETUP或PLAY請求的回覆時,我永遠不會在頭文件中獲得「content-length」字段......它從來沒有或只是在這種特殊情況下? – Toby 2012-02-21 08:48:39

+0

SETUP和PLAY請求沒有消息正文。根據RFC2326,只是在響應中返回消息體的DESCRIBE和GET_PARAMETER請求:「...返回消息體的所有方法。在此規範中,DESCRIBE和GET_PARAMETER屬於此類。」 – Ralf 2012-02-21 08:57:42

+0

好吧好吧,我想我現在就明白了!感謝您的幫助!! – Toby 2012-02-21 12:29:31

相關問題