2014-04-09 51 views
2

我使用boost asio編寫簡單的服務器/客戶端來傳輸二進制數據。特別是,我用ip:tcp :: socket使用async_write和async_read。沒什麼特別的,真的。boost asio跨平臺換行混淆

boost::asio::async_write(*mp_socket, boost::asio::buffer(data_ptr, data_size), 
         boost::bind(&TcpSocket::m_handleWrite, this, 
            boost::asio::placeholders::error, 
            boost::asio::placeholders::bytes_transferred)); 

boost::asio::async_read(*mp_socket, boost::asio::buffer(mp_buffer, m_buffer_size), 
         boost::bind(&TcpSocket::m_handleRead, this, 
            boost::asio::placeholders::error, 
            boost::asio::placeholders::bytes_transferred)); 

我隨機產生二進制數據,並在各種平臺對發送/接收測試。該代碼在相同的平臺(例如所有在Linux中,都在Windows中)工作正常,但無法跨平臺工作。

例如,左邊是在windows中接收的數據,右邊是在linux中發送的數據。唯一的區別是windows中的0D0A(CRLF)和linux中的0A(LF)。我認爲某處(在提升asio,或在winsock等),LF-> CRLF轉換正在發生。

那麼,有沒有辦法禁用轉換,因爲我正在發送二進制數據?我在boost :: asio配置中尋找一些選項(例如使用原始緩衝區,而不是流緩衝區),但找不到它。感謝您的幫助。在DATA_PTR

size_t sz = rand() % 60000; 
    char* p = (char*)malloc(sz + 4); 
    uint32_t* p_header = reinterpret_cast<uint32_t*>(p); 
    *p_header = htonl((uint32_t)sz); 
    for (size_t i = 0; i < sz; ++i) 
    { 
    p[i + 4] = rand() % 255; 
    } 
+0

通常,您提供的緩衝區不會被'async_write'或'async_read'調用修改(重載需要一個'ConstBufferSequence''應該保證這個)。差異可能發生在緩衝區本身生成的地方。你可以顯示該代碼嗎? – Chad

+0

你好乍得,你能再澄清一點嗎?哪個「緩衝區」是你的意思? boost :: asio :: buffer或者char * mp_buffer,或者其值是隨機填充的數據緩衝區? – xosp7tom

+0

你如何生成'data_ptr'的內容? – Chad

回答

0

enter image description here


數據,我認爲這個問題是因爲async_read是 「面向流」,請參閱:Short reads and writes

我認爲asio分別使用CRLFLF適用於Windows和Linux的流終結,我想在某個地方它使用的是Windows終止爲Linux流或反之亦然。

試着改變你的async_read呼籲:

mp_socket->async_read_some(boost::asio::buffer(mp_buffer, m_buffer_size), 
          boost::bind(&TcpSocket::m_handleRead, this, 
             boost::asio::placeholders::error, 
             boost::asio::placeholders::bytes_transferred)); 

我用這個方法來讀取大的二進制文件,驗證對他們的哈希所接收的文件沒有任何您所遇到的問題。