2016-08-03-信息系統實踐手記8-兩模塊通訊的一些事

来源:https://www.cnblogs.com/taichu/archive/2018/04/18/8875497.html
-Advertisement-
Play Games

layout: post title: 2016 08 03 信息系統實踐手記8 兩模塊通訊的一些事 key: 20160803 tags: 對接 卡口 黑名單 佈防 撤防 訂閱 取消 設備 列表 模型 modify_date: 2016 08 03 信息系統實踐手記8 兩模塊通訊的一些事 說明: ...



layout: post
title: 2016-08-03-信息系統實踐手記8-兩模塊通訊的一些事
key: 20160803
tags: 對接 卡口 黑名單 佈防 撤防 訂閱 取消 設備 列表 模型
modify_date: 2016-08-03
---

信息系統實踐手記8-兩模塊通訊的一些事

說明:

正文:

  • 信息系統實踐手記系列是系筆者在平時研發中先後遇到的大小的問題,其中比較典型的內容加以收集和分享。
  • 信息系統實踐手記目錄:博客園(或查看源碼的README.MD文件)

摘要:

  • 此文描述了兩個模塊通信方面的內容。

正文

在信息系統開發和對接的過程中,免不了要遇到兩個模塊之間的消息互通,即便都是自己開發的2個模塊互通,或者自己模塊和第三方某個模塊通訊。
這裡儘量不涉及具體技術(這個大家自己找資料看書),主要是掰扯一下會涉及到的一些思考和情況。

1. 對接協議的2個層次:

  • 兩個代碼實體(簡稱模塊)互相需要通訊,往往在不同的主機(PC/IP)上,也偶有在同一個主機上的,TCP/IP協議已經屏蔽了物理機的差異,通過IP/PORT來區分資源,區分模塊或功能對等實體。回過來,2個模塊要通訊,2端代碼要交互信息(數據/消息/信令/碼流/結構/隨便怎麼稱呼),參照目前互聯網的TCP/IP協議或其他奇怪協議,基本分為兩種層次:
  • A:物理實現層(對於TCP/IP中的物理層,鏈路層等)的比特流,二進位,高低電平,網卡,網路設備等支持這個協議。比如3伏特/12伏特表示0或1等等,這是電氣特性;可靠性依賴於硬體的工作特性,電氣特性,以及糾錯手段(一些數學和工程方法)。
  • B:高層(統一叫高層,就是這個意思),基於二進位bit層次上的有含義的層次,位元組流層次,byte(一般是8bit=1byte),而byte就對應了byte編碼規範,比如ASCII或UTF-8,這樣一串bytes就有邏輯含義了(26個英文字母及大小寫,自然數10個數字,特殊符號,回車換行,加減乘除符號,不可見符號等等);其實網路上傳遞的都是位元組流,而TCP/IP協議主要也是處理這個位元組流從端到端的傳送;可靠性依賴於下層A的bit流,並也可以增加適當的校驗CRC等各種手段(也是一些數學方法)
  • 所以雖然ISO/OSI的7層網路模型設計的很好,其實落實到實際實現的TCP/IP協議,也就主要分為以上A/B兩個層次,A中還細分幾個,B中也有細分但用的不多;主要理解這2個層次,從物理bit的可靠傳輸,架構其有邏輯含義的高層位元組byte傳輸,這麼個概念。後續主要就談B層了,畢竟A層次目前已經穩定,除非量子力學顛覆當前的電腦原型(節點PC),然後自然而然的可能顛覆網路基礎物理層A的電氣特性,搞些先進的,這個我們就不談了,還有5到10年就撲面而來了。

這裡只談B層;

2. TCP/IP協議主要分為TCP/UDP2種:

  • TCP/IP協議分為主要的2種,UDP/TCP:
  • TCP:面向連接(在網路基礎層A上維護的邏輯上的連接通道) 的有狀態的位元組流通訊,保證數據包的按序及正確傳送,有狀態,所以能錯誤重傳,並維護連接通道;但數據報的緩存及發送依賴於“邏輯連接通道”兩端模塊程式(往往是OS的網路驅動,網卡的驅動程式等)自主決定。所以會產生粘包及粘包如何分割的問題,這是TCP經典問題,請另查資料(或看netty官網的userguide入門章節,有比較簡單經典的描述);
    • 場景:需要可靠連接,直接拿來用的場景,犧牲一定的效率;用的較廣泛;
  • UDP:無連接,不保證數據包按照發送順序到達目的地,甚至不保證能到達目的地;它其實允許2端模塊自己通過高層協議來組織,數據包的順序檢查,丟包重傳,及狀態流轉等;等於自己實現一個小小的簡單TCP;
    • 場景: 網路環境表穩定可靠,對數據正確性及順序無特別嚴格要求,效率較高;比如區域網播放視頻等;
  • 說明:隨著網路硬體性能,模塊所在節點PC或伺服器的性能提升,也許大家覺得即使看視頻也用TCP來的更方便和效果好,那也是可以的,這無一個定論,看具體情況和項目方案的需求和實施情況而定

4. 針對TCP的幾種使用方法

  • TCP比較好用,但是有個特點就是粘包。雖然它是面向連接,有狀態維護管理,丟包重傳,且保證次序。但是兩端節點上的莊模塊的網路驅動底層庫,各自有演算法,緩存cache和策略,效率,切分包的大小(MTU)等都不同,導致接收方得到的包只在整體位元組流bytes上是一致的,但無法知道發送方每次send給底層的byte位元組是如何劃分的。這就是經典的粘包及切分問題;一般有如下幾個方法來處理;
  • 方法1:定長欄位法;
    • 這樣就不怕粘包了,發送端只管發,接收端從接受緩存不斷輪詢,如果滿了一定長度length後,就讀入;這裡當然假設TCP是有序,丟包會重傳的。
    • 優點:實現簡單;邏輯也簡單;
    • 缺點:一旦TCP傳輸有錯(網路不好,概率偶發,協議棧缺陷等,總會錯誤),則整體就會偏移,數據錯位就會錯誤;
    • 改進:根據其缺點,可在定長中增加特殊頭標記,比如定長length=64bytes,其中開始標記flag=\x0C等,當滿足兩者,就解碼為邏輯內容,內容正確就用,內容錯誤就丟棄,並找到下一個有效的定長數據片(且以flag開頭);這其實已經有一點TLV的雛形了。
  • 方法2:分隔符方式(變長欄位法);
    • 和定長欄位法相對的,就是通過一個分隔符來區分前後兩端內容,則沒斷長度可變化,分隔符不可重覆,同樣能解決粘包問題;
    • 優點:實現簡單,邏輯較簡單,比較可靠;
    • 缺點:要保證分隔符是payload(有效載荷,即實際負載和傳輸的數據)中不能包含的!而且演算法效率低下,需要每個byte都檢查是否為分隔符;
    • 改進:如果能配合定長的數據片,那其實等價於加一個flag頭。
  • 方法3:TLV方式(經典高效):
    • TLV是比較經典的方式,用的相對較多。TLV(一般指Type-Length-Value)。它的協議一般會約定一個head頭結構,包含flag和length,flag用來找到TLV的頭(是個標記位元組,不必唯一,但不能很多),找到flag後,就根據協議約定解析head頭結構,解析失敗則繼續查找flag;解析成功後,就能獲得head+body的整體長度length,從而解析得到body的數據;在body中通過一組組不定長的(length-value)結構,一個長度一個value值來承載payload,但length欄位的自身長度是固定的,一般為1都4個位元組之間,看TLV整體的協議定義;body的length和head的中length的自身長度也不必要一定一致。另外,這個type是類型的含義,是TLV協議手冊的約定,一般會說明有K組
    • 優點:高效的通過length欄位獲取value,不用每個位元組都檢查;且支持不同的數據結構;
    • 缺點:實現比較複雜,兩邊TLV協議手冊顯然比前2種方法的描述要詳細;
    • 改進:可以通過諸如JAVA的反射或其他方法,來將TLV協議通過“配置文件”的方式,讓程式自動根據清晰明瞭容易維護的配置文件來生成編解碼程式(CODEC)。

4. 針對TCP心跳的一些說明

TCP協議內容較多,有好幾本大書,但核心內容,網上也轉載很多,這裡只提一些內容。
TCP如果不在初始化socket的時候給予超時timeout設定(看tcp類庫支持哪些超時,一般如java io/NIO支持連接超時,傳輸超時等),那麼預設就是2小時(120分鐘),在120分鐘內TCP協議內部自己有心跳維持socket連接通道,
超過120分鐘,則按照狀態機變化,兩端都開始拆除TCP連接。當然,兩端莊模塊開發的如果不好,這就會導致對端有大量埠TIME_WAIT等等TCP狀態機不能順利,快速,高效的拆除並被覆用,導致資源消耗,甚至耗光65535個port口。
除了TCP自身的超時,或者網路lib庫能力範圍內給予的連接超時,傳輸超時(閑置idle超時)外,樁模塊可以人為的在邏輯層添加自己的超時和心跳機制。舉例如下:
(1)收到PING,就發PONG,收到PONG,不響應;這是對等心跳探測包,有發起者探測對方是否活著alive;
(2)兩邊約定心跳間隔時間,比如每120秒發送心跳包(比如“HB”2個字元,或某種位元組等),或者約定只有server發給client,不用反向;
特別說明:這是高層邏輯的心跳,應用層自己使用的,而且其實現根據前述3種使用方法而不同,比如你用TLV,那麼也需要額外定義一個“心跳包”的協議;

5. 用哪些類庫?

一般開發樁模塊的時候,兩端約定好傳輸協議,比如TLV,那麼就各自開發。你用熟悉的語言比如java,而且會進一步使用現成的框架,比如netty(非同步io框架),
這樣你就不用赤裸的使用java的nio自己一步步處理,不用重覆發明輪子。netty是一個非常好用的庫,開發者同時也開發了mina,兩個庫有點類似,各有千秋和側重。
詳見我整理的[ITIS-資料集合貼]中的介紹和電子書;

6. 對接協議的的安全性問題

TCP是有連接,有狀態,有序,丟包重傳的,所以他有基礎的正確性保證。但TCP完全會受到重傳攻擊,或偵聽竊聽,或篡改數據包等破壞方式。而且TCP保證的是網路層的位元組流的按序正確到達,不保證上層邏輯(應用層)認為的數據是百分百正確的。所以,有如下建議:
(1)可以根據需求,對自己的數據進行編碼,壓縮,加密;
(2)可以參考一些開源的密鑰,加密演算法,認證,證書等協議的使用;
(3)曾經這樣弄過,給payload轉為base64,並且做了MD5摘要,傳到對端MD5用來驗證數據對不對,也可作為非同步反饋的key值。

總結,總是TCP協議豐富多彩,如果熟悉一些框架和常用手段,再加上一些諸如MD5,加密壓縮演算法等,完全可以自己搭建和實現不同的傳輸協議,滿足不同情況的要求,在兩個對端樁模塊之間實現數據的傳遞。

END


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Array.prototype.uniq = function () { var arr = []; var flag = true; this.forEach(function(item) { // 排除 NaN (重要!!!) NaN 和自身不相等 // 除了NaN 其他數據 和 自己都 相等 ...
  • <div class="upload_box"> <div id="preview"> <img id="imghead" src="0.jpg" width="190" height="130"/> <!--圖片顯示位置--> </div> <b>上傳圖片</b> <input type="fil ...
  • 原因 : Vue 的組件作用域都是孤立的,不允許在子組件的模板內直接引用父組件的數據。必須使用特定的方法才能實現組件之間的數據傳遞。 props 父組件給子組件傳遞數據 props:作用是父組件給子組件傳遞數據。 語法:參考《vue(二)-父子組件語法》。 註意要點: 1: 子組件要顯式聲明需要哪些 ...
  • 最近剛辭了原來的那家公司,準備新找一份工作。其中有個公司要求會Openlayers3。一看到這個要求,就知道公司業務涉及地圖圖表比較多。 Openlayers本身是一個基於GIS地圖相關的功能豐富的JS組件庫,功能和方法很多,學起來也需要一點點慢慢學習,邊學邊用。這裡先簡單介紹一個入門實例。 代碼見 ...
  • 本文主要介紹 div 標簽設置 contenteditable = ' true ' 時,在游標位置插入輸入的內容,或在游標位置粘貼純文本內容。文中涉及知識,可參考以下: http://www.zhangxinxu.com/wordpress/2016/01/contenteditable-plai ...
  • 一、從單機到分散式: 二、分散式常見問題: 三、ACID事務的四大特性: 原子性:一次執行過程中,要麼都成功,要麼都失敗 一致性:從一個一致性狀態到另一個一致性狀態 隔離性:事務之間互不幹擾 持久性:一旦事務成功結束,它所做的操作會永久保存下來 四、CAP理論 ...待續 ...
  • 概述 1. 類 a. 類是構造對象的模板和藍圖 b. 由類構造對象的過程成為創建類的實例 c. 封裝從形式上看就是數據和行為組裝在一個包中,並對使用者隱藏數據的實現方式。其中的數據成為實例域,操縱數據的過程為方法。對每一個特定的類實例,都有一組特定的實例域值,成為對象的當前狀態。實現封裝的關鍵在於絕 ...
  • 最近由於項目驗收的事,太忙,沒有來的及更新,我不想草率的寫。我儘量把自己在工作中悟到的工作經驗分享給大家。一定要讓自己有利用價值,否則就沒有競爭力。在公司,你在老闆心中有利用價值,這樣才能加薪。做為程式員最重要的競爭力就是技術過硬,技術過硬靠的是編程思想。 在面向對象中,所有的對象都有宿主。重要的話 ...
一周排行
    -Advertisement-
    Play Games
  • Timer是什麼 Timer 是一種用於創建定期粒度行為的機制。 與標準的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時間後執行特定的操作,或者在特定的時間間隔內重覆執行操作。 它在分散式系統中具有重要作用,特別是在處理需要周期性執行的 ...
  • 前言 相信很多做WPF開發的小伙伴都遇到過表格類的需求,雖然現有的Grid控制項也能實現,但是使用起來的體驗感並不好,比如要實現一個Excel中的表格效果,估計你能想到的第一個方法就是套Border控制項,用這種方法你需要控制每個Border的邊框,並且在一堆Bordr中找到Grid.Row,Grid. ...
  • .NET C#程式啟動閃退,目錄導致的問題 這是第2次踩這個坑了,很小的編程細節,容易忽略,所以寫個博客,分享給大家。 1.第一次坑:是windows 系統把程式運行成服務,找不到配置文件,原因是以服務運行它的工作目錄是在C:\Windows\System32 2.本次坑:WPF桌面程式通過註冊表設 ...
  • 在分散式系統中,數據的持久化是至關重要的一環。 Orleans 7 引入了強大的持久化功能,使得在分散式環境下管理數據變得更加輕鬆和可靠。 本文將介紹什麼是 Orleans 7 的持久化,如何設置它以及相應的代碼示例。 什麼是 Orleans 7 的持久化? Orleans 7 的持久化是指將 Or ...
  • 前言 .NET Feature Management 是一個用於管理應用程式功能的庫,它可以幫助開發人員在應用程式中輕鬆地添加、移除和管理功能。使用 Feature Management,開發人員可以根據不同用戶、環境或其他條件來動態地控制應用程式中的功能。這使得開發人員可以更靈活地管理應用程式的功 ...
  • 在 WPF 應用程式中,拖放操作是實現用戶交互的重要組成部分。通過拖放操作,用戶可以輕鬆地將數據從一個位置移動到另一個位置,或者將控制項從一個容器移動到另一個容器。然而,WPF 中預設的拖放操作可能並不是那麼好用。為瞭解決這個問題,我們可以自定義一個 Panel 來實現更簡單的拖拽操作。 自定義 Pa ...
  • 在實際使用中,由於涉及到不同編程語言之間互相調用,導致C++ 中的OpenCV與C#中的OpenCvSharp 圖像數據在不同編程語言之間難以有效傳遞。在本文中我們將結合OpenCvSharp源碼實現原理,探究兩種數據之間的通信方式。 ...
  • 一、前言 這是一篇搭建許可權管理系統的系列文章。 隨著網路的發展,信息安全對應任何企業來說都越發的重要,而本系列文章將和大家一起一步一步搭建一個全新的許可權管理系統。 說明:由於搭建一個全新的項目過於繁瑣,所有作者將挑選核心代碼和核心思路進行分享。 二、技術選擇 三、開始設計 1、自主搭建vue前端和. ...
  • Csharper中的表達式樹 這節課來瞭解一下表示式樹是什麼? 在C#中,表達式樹是一種數據結構,它可以表示一些代碼塊,如Lambda表達式或查詢表達式。表達式樹使你能夠查看和操作數據,就像你可以查看和操作代碼一樣。它們通常用於創建動態查詢和解析表達式。 一、認識表達式樹 為什麼要這樣說?它和委托有 ...
  • 在使用Django等框架來操作MySQL時,實際上底層還是通過Python來操作的,首先需要安裝一個驅動程式,在Python3中,驅動程式有多種選擇,比如有pymysql以及mysqlclient等。使用pip命令安裝mysqlclient失敗應如何解決? 安裝的python版本說明 機器同時安裝了 ...