boost asio 連線管理11 如何關閉連線

2021-09-06 16:19:52 字數 1277 閱讀 3839

在實際產品執行中,對連線管理有了更新的認識,這裡分享一下。

shared_ptr的引用計數器決定了連線物件的生命週期。這裡我說的連線物件就是在我的前文:

中的client物件:

[cpp]view plain

copy

print

?#include "core/connection.h"  

#include 

using namespace std;  

class client: public connection catch (std::exception& e)     

}    

如果要使用closesocket,多執行緒環境下必須小心。比如我碰到過這樣的情況:乙個執行緒檢查到了超時,然後呼叫client::closesocket方法,同時另乙個執行緒正在該client上發起了非同步的讀/寫操作,結果程序崩潰了。boost asio不允許這樣做。

參考:

如果就堅持不用closesocket行麼,我碰到另一種情況,async_write/async_read會阻塞,結果shared_ptr的引用計數不會為0,所以client物件無法被銷毀。那麼怎麼安全的呼叫closesocket的呢?用strand,下面是**:

[cpp]view plain

copy

print?

void client::toclose()   

void client::doclose()   

其他執行緒就只需要呼叫toclose函式即可。

由於strand_.post的橋梁作用,closesocket會在io_service執行的執行緒池中被保護。就不會出現和async_read/async_write同時被執行的情況。

在實際程式設計中我們可能由於很多原因要關閉連線,比如前面說的心跳超時,也有收到了不正確的資料,或者在asio傳遞出來的網路錯誤,又或者是收到了關閉程序的訊號。

無論何種原因,都可以採用上面的方式進行關閉連線。所以原則只有乙個,記住shared_ptr的生命週期即可。

如何在這種情況下優雅的退出程序是個問題,否則退出時程式會crash,留下core檔案。這種情況是:

1. 執行緒池中執行這io_service物件,進行非同步的讀/寫操作

2. 乙個執行緒定期檢查資料庫中的事件訊息,並傳送給所有遠端終端,同時檢查每個連線的心跳超時時間。

3. 乙個全域性的map物件儲存了所有client的shared_ptr。

在以後的文章中會探索。

HTTP連線管理

http通訊是由tcp ip承載的,tcp ip是全球計算機及網路裝置都在使用的一種常用的分組交換網路分層協議集。http連線實際上就是tcp連線和一些使用連線的規則。tcp的資料是通過名為ip分組 或ip資料報 的小資料塊來傳送的。http要傳送一條報文時,會以流的形式將報文資料的內容通過一條開啟...

TCP連線管理

tcp是面向連線的協議,因此每個tcp連線都有三個階段 連線建立 資料傳送和連線釋放。tcp連線的管理就是使運輸連線的建立和釋放都能正常進行。在tcp連線建立的過程中,要解決以下三個問題 要使每一方都能確知對方的存在。要允許雙方協商一些引數 如最大視窗值 是否使用視窗擴 項 時間戳選項以及服務質量等...

TCP 連線管理

本節將介紹一條tcp連線是如何建立和拆除的。此處假設客戶機a上面的乙個程序想要和服務 器b上的乙個程序建立一條tcp連線。本文前面介紹的是比較正常的連線和拆除,特殊的會在後面介紹。第一步客戶機a的tcp會向伺服器的tcp傳送乙個不包含應用層資料的資料的tcp報文段。該報文段中首部標誌位s yn被置為...