主頁 > 軟體設計 > 670-聊天服務器和客戶端如何保證訊息的可靠傳輸

670-聊天服務器和客戶端如何保證訊息的可靠傳輸

2021-10-10 21:04:50 軟體設計

如何保證訊息的可靠傳輸?

意思是:客戶端把訊息發送出去了,只要客戶端這里顯示他的訊息發送成功,就要保證對端一定要收到,要么收不到,客戶端就顯示發送失敗,用戶后續選擇重新發送訊息,如果客戶端顯示訊息發送成功,就一定保證對端一定收到這條訊息,
我們可以在業務層實作訊息的確認機制(結合心跳):在訊息發送之后對端給予回應,
集群聊天服務器是基于TCP協議實作的,TCP協議本身是可靠的傳輸協議,在發送資料的時候,有超時重傳機制,TCP發送每一個資料的時候,都會等待得到接收方回傳的ACK訊息確認,它如果得不到ACK,就會超時重傳,選擇重新發送這個資料,得到ACK確認之后,保證訊息發送成功了,
為什么業務層上還要實作訊息確認機制呢?
我們看看下面這張圖:
在這里插入圖片描述
這個send的回傳值大于0,發送成功了,回傳了發送成功的位元組數,但是并不代表著這條訊息跑到對端,對端接收到了,
send怎么可能是呼叫的時候還包括客戶端往服務器發送的程序和服務器接收到了,然后回應,回應成功了,send才回傳?不可能的!如果是這樣的話,send呼叫所花費的時間就非常長了,尤其是在網路環境非常復雜的情況下,這樣做,耗費的時間是非常長的,

當我們在行程的用戶空間的資料,就是上圖中的buf,然后它要發送,呼叫系統的介面send,把用戶空間的buf資料拷貝到內核空間的TCP發送緩沖區中,因為TCP是流式服務,有TCP的發送緩沖區和接識訓沖區, UDP資料報協議是沒有發送緩沖區和接識訓沖區的,對于TCP發送來說,send發送成功,僅僅只是代表說把用戶空間的buf里面的多少資料拷貝到內核空間的TCP發送緩沖區中,還沒有把資料發送到對端,
在這里插入圖片描述
內核空間的TCP發送緩沖區的資料,是由內核的TCP協議堆疊(相當于是TCP協議的代碼模塊),專門把發送緩沖區的資料(根據滑動視窗機制,可以根據網路狀況,調節發送緩沖區的資料的發送的一個快慢,調節流量,把資料發送出去),
send只是把資料發送到TCP的發送緩沖區中,然后send就回傳了,用戶空間繼續向下執行代碼,所以,send成功回傳,并不能說明訊息到達對端了,
在這里插入圖片描述
內核空間處理TCP發送緩沖區的資料,開啟TCP的傳輸,TCP傳輸的時候,傳1個資料報文,在這里,有可能出現2種情況:
情況1、從C端發送到S端后,由于網路的情況比較復雜,網路比較擁塞,資料報文經常切換網路節點的路由,導致這個資料報文的TTL在沒有到達S端,已經超過上限了,直接被路由器把當前的資料報文丟棄了,到達不了S端了,
情況
情況 2、這個報文到達S端了,基于TCP的可靠傳輸,對每一個發送的資料報文,都要進行回應,這個ACK可能就碰到了情況1了,導致ACK報文在網路中丟了,沒有到達C端,
上面2種情況都是屬于報文傳輸失敗了,
在這里插入圖片描述
當C端第一次發送報文的時候,TCP協議堆疊里面就會起1個超時重傳定時器,當我們發送的資料報文到達S端,S端回傳的這個ACK也到達C端了,那我們就可以繼續發送下一個報文了,
如果說,當我第一次發送該報文,超時重傳定時器已經超時了,還沒有得到S端的回應ACK,它就會重新去發送這個資料報文,力求這個S端可以回傳這個報文的ACK,如果后面S端回應了這個ACK,說明這個報文傳輸成功,如果還是出現了資料報文沒有發到S端,或者S端回傳的ACK在中途丟了,C端沒有收到,超過定時時間,它又要進行超時重傳,超時重傳是有上限次數的,是不可能無限次超時重傳下去的,網路情況是很復雜的,如果網路情況復雜,搞了很多很多的TCP報文超時重傳,一直不斷重傳,整個內核所占用的資源永遠得不到釋放,這是非常不好的,所以,超時重傳超過一定次數,TCP會發一個RST(連接重置)的報文給到對端,整個超時重傳流程就結束了,TCP的超時重傳是在一定程度上保證了報文的可靠性傳輸,但是如果網路環境比較差,一直重傳都沒有得到回應,TCP發送一個RST連接重置報文就不管了,訊息還是沒有到達S端!!!所以,我們聊天訊息的可靠傳輸肯定是不能靠協議來保證的,
**內核空間是不可能給用戶提供一個回呼函式提醒訊息沒有傳輸成功的,**尤其是在TCP協議堆疊,TCP協議堆疊是負責網路模塊的,其本身就隨著網路環境的復雜,TCP協議堆疊本身實作也很復雜,如果在這里給用戶注冊一個回呼函式,萬一回呼函式里訪問了一個空指標,直接把內核的TCP模塊廢掉了,怎么辦?
Linux的信號signal,信號的回呼操作內核發給你當前行程的信號,可以寫代碼讓這個信號掛掉,因為信號是某個行程的信號,把行程搞掛掉,就是讓這個行程不要運行了而已,但是TCP協議堆疊是給的用戶空間的所有應用程式服務的,萬一給你注冊回呼,把內核掛了,怎么辦???

資料傳輸的程序:傳輸層(TCP)-》網路層(IP)-》資料鏈路層(MAC)
網路層以上是通過IP地址定位主機的,網路層以下(從鏈路層開始)是通過Mac2地址定位主機的,Mac是真真正正,把資料一幀一幀的發送到網路上了,Mac發送一幀的大小:上限是MTU 1500位元組,TCP的報頭是20位元組,IP的報頭是20位元組,一般來說,一個網卡的一幀最多攜帶1500-40=1460位元組資料,如果我們發送的資料的大小是超過1460位元組的,我們在IP層可以進行分包,分片傳輸,分成1小片1小片,發送到對后,可以把這些小的分片組成原始的資料,

正確方法

我們還是得在業務層上實作訊息的可靠傳輸!!!
我們把客戶端要發送的訊息都快取起來,因為客戶端要實作訊息的可靠傳輸,而且,每一條訊息都有seq序列號,不管是一對一聊天,還是群聊,每一個物件在每一個聊天的會話都有訊息的序列號seq,
客戶端A連續發送3條訊息:
message1 seq:0
message2 seq:1
message3 seq:2
0號訊息先發送出去,正常情況下,這條訊息發送出去以后,客戶端要等待服務端對這個訊息的回應ACK,然后從正常流程來說,客戶端發送1號訊息,
以此類推,
或者說,在客戶端中,也沒有必要按照順序發送訊息,為了性能來說,可以把訊息全部發送出去,因為每條訊息都有seq序列號,在對端收到訊息以后,會對訊息進行快取,按順序顯示訊息,所以發送方可以一次性全部發送出去,但是發送方一定要等待每個訊息回應的ACK,哪個訊息回應了ACK,就說明哪個訊息是可靠傳輸到了對端(因為訊息都有序列號,可以區分出來),客戶端發送到服務器,服務器轉發到另一個客戶端上,都是根據這個方法,如果客戶端收到某條訊息的ACK了,就可以把這條訊息從本地快取洗掉了,說明這個訊息后面不用進行重傳了,如果客戶端得不到對1號訊息的ACK的話,我們可以在客戶端設定超時重傳機制,如果3毫秒沒有收到這條訊息的ACK,再重新發這條訊息,以此類推,如果重復傳3次還沒有收到這條訊息的ACK,我們就給客戶端顯示:該訊息發送失敗,等下一次網路恢復,由用戶來選擇是否重傳,
在這里插入圖片描述
客戶端也可以通過實作心跳機制來檢查服務端的連接能不能連通,心跳正常,發送訊息肯定沒問題,比如說,客戶端隔1秒發送一次心跳,如果服務端沒有回應,客戶端的心跳計數就從0加到1,如果收到服務端的回應,就減1,以此類推,如果心跳計數超過3,客戶端就判定和服務端的連接斷開了,客戶端就是紅色狀態了,如果客戶端沒有退出APP的話,就一直發送心跳,如果發著發著,網路恢復了,客戶端發了一個心跳,服務端回應了,客戶端把心跳計數的3改為0,繼續發送心跳,如果付訓復了,現在又出現問題了,心跳計數又超過3了,又判定和服務端連接有問題了
也就是說,心跳給了和服務端的連接狀態,我們發送訊息的時候可以先看連接的狀態,如果是OK的話,心跳訊息都能互動成功,我們發送普通的訊息肯定也可以收到ACK回應的,如果心跳已經是失敗的,我們在全域有一個狀態(和服務器的狀態)已經不可用的狀態(inactive),我們客戶端在發送訊息就直接是不能發送,直接給用戶顯示發送失敗,不用嘗試發送了,心跳都失敗,發送普通訊息還能成功???等下一次心跳恢復正常的話,我們再去發送訊息,

我們在TCP,UDP都會設定心跳機制來復雜的網路環境中,客戶端檢測服務端鏈路是否正常,服務端檢測客戶端是否在線,

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/307766.html

標籤:其他

上一篇:打開帶有whereCondition的子表單的表單

下一篇:Java后端兼職前端,大勢所趨,??Vue腳手架??助你騰飛翱翔(建議收藏)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more