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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...