2013-01-17 96 views
3

這是我的場景。從單個線程在套接字上請求幾個異步寫入。同一個線程調用io_service::run。所以我假設所有的完成處理程序都以相應的異步寫入啓動順序執行。關閉並關閉最後完成處理程序中的套接字是否正常?如何異步關閉套接字

編輯:我正在使用TCP協議。

+1

至少在Boost.Asio中調用單個套接字的乘法異步寫入甚至不安全。只有一個套接字才能激活異步讀寫。 – weggo

+0

感謝您指出。 – pic11

回答

3

您需要從第一個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()

+0

既然你指出了我答案中的一個缺陷,我已經刪除了它。現在只需要在這裏添加關於TCP vs UDP的信息,並且您的答案既正確又完整。無論如何。 –

+0

爲什麼在這種情況下使用'bind'? –

+0

@Yam問題特定於TCP套接字。我在我的僞代碼中使用了'boost :: bind()',因爲[asio examples]中的大多數完成處理程序(http://www.boost.org/doc/libs/release/doc/html/boost_asio/example/echo /async_tcp_echo_server.cpp)使用非常相似的技術。 –

0

我假設你有一個TCP套接字(因爲UDP協議是無連接的)。

如果你做這樣的事情:

start_async_write(first) 
start_async_write(second) -> close socket on complete 
io_service.run() 

一切都會好的,你寫將被序列化,run()方法將返回後的插座close方法將完成處理函數中調用。

+1

顯然這是不正確的,由boost :: asio的文檔。 –

+1

async_write()與其名稱所暗示的是異步的,在第一個操作完成並實現確定性行爲之前,不能調用第二個操作。 –

+0

爲什麼不呢?在窗口async_write只是在引擎蓋下調用WriteFile。第二次寫入將暫停,直到第一次完成。完成處理程序將按完成端口上的FIFO順序排隊。如果您創建了許多優秀的寫入,則會發生內存不足異常。 – Lazin