關於使用boost asio庫 出現的一些問題的總結
最近在使用boost庫的時候,因為可能是自己的c++學的還不是很紮實吧,出現了很多令人啼笑皆非的錯誤。而且,我也不太能從一些錯誤提示中找到正確的解決思路。下面就是我的一個錯誤總結吧。
一開始我對於boost asio庫的執行模式不是很理解,經過一些錯誤總算有一點頭緒。
io_service的作用
首先asio庫主要就是對一些io進行操作,其中就有我的專案比較需要的網路socket的一些io功能。
首先,asio封裝了一個io_service這樣一個類,用來連線使用者的程式和作業系統之間的一些io服務。
在asio庫裡面你可以選擇以同步或者非同步的方式對IO進行操作,非同步操作的方法前面會有async_
針對同步的操作
使用者程式在需要io操作的時候會將任務或者請求傳送給io_service,之後io_service會接收到作業系統的一些執行結果,之後如果錯誤的話會丟擲異常
針對非同步的操作
使用者程式的io操作還是會由io_service來處理但是非同步就意味著,不會在原地等待操作完成,所以會將任務放在佇列裡面。當系統的任務完成之後就會將結果放在佇列裡面通知io_service並且呼叫相應的回撥函式。要注意的是回撥函式的格式一定要準確,簽名一定要保證其正確性。
注意:io_service一般會在呼叫第一個非同步函式之後呼叫,io_service的run函式阻塞接收相應的未完成的回撥函式。
異常的形式
- IO物件丟擲boost::system::system_error型別的異常
try
{
socket_->open(ip::tcp::v4());
}
catch(boost::system::system_error const& e)
{
std::cout << "Warning: could not connect : " << e.what() << std::endl;
}
- 在非同步函式的回撥函式裡面我們會使用error_code來檢視錯誤情況,但不會丟擲異常
void Handle::ReadHandler(const boost::system::error_code& ec, size_t bytes_transferred)
{
if(ec)
{
std::cout << "READ failed, error code:" << ec.value()
<< " category name:" << ec.category().name()
<< " message:" << ec.message();
return;
}
}
錯誤碼125 : operation canceled
出現這個錯誤是因為我的服務端在accept客戶端之後沒有儲存好socket,之後呢析構了。這就會導致連線直接被中斷,如果連線被中斷就會直接呼叫所有的回撥函式,並且返回一個錯誤碼就是125.或者是一些回撥函式返回misc:2這個錯誤碼。
關於一些類的安全性
有些類比如socket,boost::streambuf為了保護例項是獨一無二的,會將拷貝建構函式放在私有的許可權下。也就是說禁止拷貝構造,所以我們可以看到很多地方我們都是用引用變數,避免拷貝構造,並且節省效率。我之前不清楚,現在才理解。