2012-05-11 133 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也可能有帮助。

我想你需要明确地从客户端发送接收确认,即滚动你自己的应用层协议。