2012-05-11 136 views
3

所以我嘗試了boost :: asio並測試了阻塞回聲示例。他們似乎並沒有完全封鎖它似乎。至少不像我預期的那樣。關於boost :: asio套接字和阻塞

是否有可能擺脫任何形式的緩衝或什麼是您可以擁有的最小緩衝區大小?它看起來像10000字節太小。

以下代碼在塊寫入之前會經過2次寫入。如果我將boost :: asio :: transfer_exactly(10000)參數添加到寫入,它仍然是2. boost :: asio :: transfer_exactly(5000)讓我寫入5個寫入。

那麼這個網絡/ io/asio的東西是如何工作的?就像我只想發送一個字節並等待它到達另一端,而沒有任何額外的通信。

服務器:

boost::asio::io_service io_service; 

tcp::acceptor a(io_service, tcp::endpoint(tcp::v4(), 12346)); 
tcp::socket sock(io_service); 

a.accept(sock); 
sock.non_blocking(false); 
boost::asio::socket_base::send_buffer_size option(10000); 
sock.set_option(option); 

while(true) { 
    char data[10000]; 

    boost::asio::socket_base::bytes_readable bytes_readable_cmd(true); 
    sock.io_control(bytes_readable_cmd); 
    std::size_t bytes_readable = bytes_readable_cmd.get(); 
    if(bytes_readable) { 
     /**/ 
    } 

    boost::asio::write(sock, boost::asio::buffer(data, 10000)); 
    printf("#\n");Sleep(10); 
} 

客戶:

boost::asio::io_service io_service; 

tcp::resolver resolver(io_service); 
tcp::resolver::query query(tcp::v4(), "localhost", "12346"); 
tcp::resolver::iterator iterator = resolver.resolve(query); 

tcp::socket sock(io_service); 
boost::asio::connect(sock, iterator); 
sock.non_blocking(false); 
+0

爲什麼要發送數據並等待直到它在另一側收到? –

+0

假設我不在乎接收器程序是否真的獲得了數據並處理了它。我只想要TCP協議爲我提供的。所以我期待asio的'發送'/'寫'塊,直到接收器被稱爲'recv'。沒關係,如果asio在場景後面處理不同的話。我只是好奇。 – Ivarpoiss

回答

4

我認爲在這種情況下,只有write實際塊時,底層緩衝區已滿。

這從msdn報價將是適當的位置:

發送功能的順利完成並不表示數據已成功交付和接收到收件人。此功能僅表示數據已成功發送。

如果傳輸系統中沒有可用的緩衝空間來保存要傳輸的數據,則發送將被阻塞,除非套接字已被置於非阻塞模式。

我試着寫了超過64KB(從65537開始),它在第一次調用時被阻塞。

這不是Asio的工作方式,而是TCP和套接字如何工作。這answer也可能有幫助。

我想你需要明確地從客戶端發送接收確認,即滾動你自己的應用層協議。