這是我的場景。從單個線程在套接字上請求幾個異步寫入。同一個線程調用io_service::run
。所以我假設所有的完成處理程序都以相應的異步寫入啓動順序執行。關閉並關閉最後完成處理程序中的套接字是否正常?如何異步關閉套接字
編輯:我正在使用TCP協議。
這是我的場景。從單個線程在套接字上請求幾個異步寫入。同一個線程調用io_service::run
。所以我假設所有的完成處理程序都以相應的異步寫入啓動順序執行。關閉並關閉最後完成處理程序中的套接字是否正常?如何異步關閉套接字
編輯:我正在使用TCP協議。
您需要從第一個async_write()
的完成處理程序中調用async_write()
。僞代碼如下
boost::asio::io_service ios;
boost::asio::ip::tcp::socket socket(ios);
void
handler2()
{
socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
socket.close();
}
void
handler1()
{
async_write(socket, boost::bind(&handler2));
}
int
main()
{
async_write(socket, boost::bind(&handler1));
}
注意,documentation明確規定一個優秀的操作可以在飛行中:
此操作在零或多次調用方面落實到 流的
async_write_some
功能,並且被稱爲合成的 操作。該程序必須確保該流不會執行寫入操作(例如async_write
,流的async_write_some
函數或執行寫入的任何其他組合操作),直到該操作完成爲 。
這就是爲什麼在單個套接字上調用多個async_write()
操作是一個壞主意。或者,使用scatter operation將兩個緩衝區發送到一個async_write()
。
既然你指出了我答案中的一個缺陷,我已經刪除了它。現在只需要在這裏添加關於TCP vs UDP的信息,並且您的答案既正確又完整。無論如何。 –
爲什麼在這種情況下使用'bind'? –
@Yam問題特定於TCP套接字。我在我的僞代碼中使用了'boost :: bind()',因爲[asio examples]中的大多數完成處理程序(http://www.boost.org/doc/libs/release/doc/html/boost_asio/example/echo /async_tcp_echo_server.cpp)使用非常相似的技術。 –
我假設你有一個TCP套接字(因爲UDP協議是無連接的)。
如果你做這樣的事情:
start_async_write(first)
start_async_write(second) -> close socket on complete
io_service.run()
一切都會好的,你寫將被序列化,run()
方法將返回後的插座close
方法將完成處理函數中調用。
顯然這是不正確的,由boost :: asio的文檔。 –
async_write()與其名稱所暗示的是異步的,在第一個操作完成並實現確定性行爲之前,不能調用第二個操作。 –
爲什麼不呢?在窗口async_write只是在引擎蓋下調用WriteFile。第二次寫入將暫停,直到第一次完成。完成處理程序將按完成端口上的FIFO順序排隊。如果您創建了許多優秀的寫入,則會發生內存不足異常。 – Lazin
至少在Boost.Asio中調用單個套接字的乘法異步寫入甚至不安全。只有一個套接字才能激活異步讀寫。 – weggo
感謝您指出。 – pic11