1 net_plugin_impl::connect(connection_ptr c) 函數用於解析地址,內部異步回調async_resolve
async_resolve 傳遞了lambda表達式,若是err爲零,則調用connect鏈接指定的地址
2 void net_plugin_impl::connect( connection_ptr c, tcp::resolver::iterator endpoint_itr ) 該函數將connection鏈接指定地址
內部調用async_connect進行異步鏈接,若是鏈接成功,回調lambda表達式。lambda表達式中取出connection的weak_ptr,這麼作爲防止shared_ptr互相引用致使內存沒法釋放。若是鏈接失敗關閉socket鏈接,若是地址錯誤關閉socket從新鏈接。
鏈接成功後,調用start_session,開始監聽該描述符的讀事件,而且開始發送握手消息send_handshake()session
3 bool net_plugin_impl::start_session( connection_ptr con )
開始鏈接,內部調用start_read_message(),而且增長鏈接會話數量。
4 void net_plugin_impl::start_read_message( connection_ptr conn ) 讀取消息函數,內部較爲複雜。
內部將shared_ptr connection_ptr 賦值給connection_wptr(weak_ptr)類型變量weak_conn,也是爲了防止互相引用shared_ptr形成內存沒法回收,minimum_read爲要讀取的字節數,若是conn->outstanding_read_bytes 非0,則等於conn->outstanding_read_bytes,不然等於消息頭大小。同時判斷是否設置低水位標記,若是設置了低水位標記,則將低水位大小設置爲取minimum_read和固定的max_socket_read_watermark的最小值。同時實現lambda表達式賦值給completion_handler,completion_handler主要功能判斷傳輸字節是否所有傳輸完成。未完成,則返回差值。app
5 接着 void net_plugin_impl::start_read_message( connection_ptr conn )內部調用了async_read,設置異步讀取數據,有消息到來會觸發回調lambada表達式。當completion_handler返回0中止讀取。lambda函數內部,conn->outstanding_read_bytes.reset()重置請求等狀態,
conn->pending_message_buffer.bytes_to_write()表示pending_message_buffer剩餘空間,還可讀取多少數據。
conn->pending_message_buffer.
conn->pending_message_buffer.bytes_to_read() 表示pending_message_buffer已經讀取多少 字節,用戶須要從
pending_message_buffer中讀取多少。
conn->outstanding_read_bytes表示buffer還有多少字節沒有讀取。異步
判斷bytes_transferred > conn->pending_message_buffer.bytes_to_write(),視爲異常,由於可用空間不足了 ,沒辦法接收。
conn->pending_message_buffer.advance_write_ptr(bytes_transferred); 將寫指針向後推動bytes_transferred字節。
write_ptr指向了pending_message_buffer的可用空間。bytes_to_write()返回可用字節數。
若是conn->pending_message_buffer.bytes_to_read() > 0,則會一直循環,直到讀完buffer中全部數據。
若是bytes_in_buffer < message_header_size,則將頭部未讀取的數據放入outstanding_read_bytes中。不然說明讀完包頭數據,pending_message_buffer.peek,讀取4字節數據寫入message_lenghth,肯定數據大小。
auto total_message_bytes = message_length + message_header_size;爲整個數據包大小,bytes_in_buffer >= total_message_bytes 說明此時buffer已經接受完數據,調用 conn->process_next_message()處理。不然,就將剩餘未讀完的數據放入outstanding_read_bytes中,
available_buffer_bytes表示可用字節數,若是可用字節數不足,則擴充pending_message_buffer大小。socket
6 bool connection::process_next_message(net_plugin_impl& impl, uint32_t message_length)處理消息。
位移代碼沒看明白,註釋的意思是保存序列化前的原始信息。以後,blk_buffer.resize(message_length);從新設置大小爲message_length長度,
auto index = pending_message_buffer.read_index();找到當前的讀索引,peek函數將message_length長度的數據讀入blk_buffer中。
以後建立datastream ds用來反序列化。將消息寫入net_message中。接着定義了msgHandler 對象m,構造函數中傳入net_plugin_impl和connection共享指針,調用msg.visit(m)。msgHandler的定義和實現
msgHandler重載了()運算符,當類msgHandler對象傳參(msg)時會調用impl.handle_message(c,msg)。如msgHandler h(msg)實際調用的
impl.handle_message(c,msg)。
net_message爲static_variant類型,static_variant類中實現了visit函數
visit內部調用apply函數,apply函數內部調用了visitor對象傳參data,visitor就是上一層的msgHandler。
net_plugin_impl::handle_message 根據參數傳入不一樣,實現了不一樣的函數調用。
這就是所說的visitor模式。經過net_message(static_variant類型)調用封裝的visit函數,visit內部調用了visitor對象的傳參,只要重載()(param)就能夠實現調用。msgHandler重載operator()(const T& msg),因此調用impl.handle_message(c,msg),而msg爲不一樣類型,因此可實現上面的不一樣調用。async
謝謝關注個人公衆號tcp