2016-10-19 51 views
2

我正在寫一個應該監聽域套接字的客戶端。我打開一個同步連接,做一個同步寫入,並且我知道服務器發送一個有效的響應,因爲我在套接字上使用了socat到eavesdropAsio沒有發現遠程系統的回覆

除了我的asio::read()被調用但從不返回任何數據。我傳給它的緩衝區總是空的。這裏是我的代碼:

void operator>>(const vector<unsigned char> input, Socket &socket) { 
     const size_t size = input.size(); 
     const size_t bytes = asio::write(socket.connection_socket, asio::buffer(input, size)); 
     if (bytes != size) { 
     const std::error_code ec; 
     throw std::system_error(ec, fmt::format("Tried to send {0} bytes but sent {1} instead.", size, bytes)); 
     } 
     string buffer; 
     asio::read(socket.connection_socket, asio::buffer(buffer)); 
     std::cerr << buffer << std::endl; 
    } 

這些都是我用來連接到插座屬性:

io_service run_loop; 
stream_protocol::socket connection_socket; 
datagram_protocol::endpoint domain_socket_ep; 

Socket是一個簡單的類,包裝所有短耳代碼,其中的運算符重載上述聲明。

回答

1

asio::read函數將讀取至多asio::buffer_size(asio::buffer(buffer))字節。在你的情況下,buffer是空的,所以它最多可以讀取零字節。

Asio不會調整您傳遞給它的緩衝區的大小,因此您需要將buffer調整爲您希望獲得的最大大小。

此外,asio::read函數可能實際上讀取較少的字節,然後輸入緩衝區的大小。它讀取的實際大小從該函數返回。因此,如果你想讀取/寫入完全適合緩衝區的字節數,你需要做這樣的事情:

void read_to_buffer(asio::ip::tcp::socket& s, asio::buffer buffer) { 
    size_t read = 0; 
    size_t n = asio::buffer_size(buffer); 
    while (read < n) { 
     read += asio::read(s, buffer + read)); 
    } 
} 

void write_from_buffer(asio::ip::tcp::socket& s, asio::buffer buffer) { 
    size_t written = 0; 
    size_t n = asio::buffer_size(buffer); 
    while (written < n) { 
     written += asio::write(s, buffer + written)); 
    } 
} 

void operator>>(const vector<unsigned char> input, Socket &socket) { 
     // TODO: convert between host and network byte order 
     auto& s = socket.connection_socket; 
     { 
     const uint32_t size = input.size(); 
     write_from_buffer(s, asio::buffer(&size, sizeof(size)); 
     write_from_buffer(s, asio::buffer(input)); 
     } 
     { 
     uint32_t size = 0; 
     read_to_buffer(s, asio::buffer(&size, sizeof(size))); 
     string payload(size, 'x'); 
     read_to_buffer(s, asio::buffer(payload)); 
     std::cerr << payload << std::endl; 
     } 
} 
+0

不知道我明白。寫入套接字很好,asio只是不讀取它。爲什麼你需要寫和讀兩次?另外,不是read_to_buffer()和asio :: read_some一樣嗎? – ruipacheco

+0

「_asio只是不從它讀取_」通過傳遞一個字符串大小爲零的asio ::讀取函數,你告訴asio讀取零字節。 TCP套接字不知道您發送了多少個字節。 「_as asio :: read_some_」,抱歉,我沒有看到[API]中列出的'asio :: read_some'函數(http://www.boost.org/doc/libs/1_62_0/doc/html/ boost_asio/reference.html),你是指哪一個? –

+0

我的意思是socket.read_some():http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/basic_stream_socket/read_some/overload1.html – ruipacheco