1. 程式人生 > >關於使用boost asio庫 出現的一些問題的總結

關於使用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為了保護例項是獨一無二的,會將拷貝建構函式放在私有的許可權下。也就是說禁止拷貝構造,所以我們可以看到很多地方我們都是用引用變數,避免拷貝構造,並且節省效率。我之前不清楚,現在才理解。