国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【算法】狀態(tài)之美,TCP/IP狀態(tài)轉(zhuǎn)換探索

這篇具有很好參考價值的文章主要介紹了【算法】狀態(tài)之美,TCP/IP狀態(tài)轉(zhuǎn)換探索。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

最近城市里甲流肆虐,口罩已經(jīng)成為了出門必備的物品。小悅也不得不開始采取防護(hù)措施,上下班過程中,將口罩戴起來以保護(hù)自己不受病毒的侵害。

每天下班后,小悅總是喜歡投入到自己的興趣愛好中,她熱衷于翻閱與IT相關(guān)的資料,希望能夠更深入地了解計算機(jī)科學(xué)。而她的大學(xué)同學(xué)小欣,則總是拿她開玩笑:“小悅啊,你是不是該考慮一下找男朋友?每天都在研究這些枯燥的算法,這可不像你啊?!?小悅總是笑笑不作回應(yīng),她對自己的研究充滿熱情,對男朋友的事情并不著急。

最近,小悅無意中看到了一篇關(guān)于TCP/IP狀態(tài)轉(zhuǎn)換的介紹,這個算法細(xì)節(jié)并未詳細(xì)闡述,只在網(wǎng)上看到了狀態(tài)圖的介紹。這激發(fā)了她深入研究TCP/IP有限狀態(tài)機(jī)的興趣,她決定通過實現(xiàn)這個算法來更好地理解TCP/IP協(xié)議各狀態(tài)跳轉(zhuǎn)的工作原理。

在實現(xiàn)TCP/IP有限狀態(tài)機(jī)模擬算法的過程中,小悅遇到了許多困難和挑戰(zhàn)。她需要設(shè)計一個能夠跟蹤TCP連接狀態(tài)的算法,并且需要使用字典來定義狀態(tài)之間的轉(zhuǎn)換規(guī)則。每個狀態(tài)作為字典的鍵,對應(yīng)的值是另一個字典,該字典包含了從當(dāng)前狀態(tài)觸發(fā)的事件和下一個狀態(tài)之間的映射關(guān)系。

為了實現(xiàn)這個算法,小悅開始思考如何著手。她首先定義了一個名為TraverseStates的方法,該方法接受一個字符串?dāng)?shù)組作為輸入,該數(shù)組包含了TCP連接中發(fā)生的事件。然后,她使用一個嵌套的字典tome來定義狀態(tài)之間的轉(zhuǎn)換規(guī)則。

在方法的主要邏輯中,小悅通過迭代給定的事件數(shù)組,從當(dāng)前狀態(tài)開始根據(jù)事件觸發(fā)狀態(tài)的轉(zhuǎn)換。如果在轉(zhuǎn)換規(guī)則中找不到與當(dāng)前狀態(tài)和事件匹配的轉(zhuǎn)換關(guān)系,就返回"ERROR"。如果成功完成了所有事件的處理,最終返回最終狀態(tài)。

在實現(xiàn)過程中,小悅遇到了許多問題。例如,有時她會遇到事件數(shù)組中存在不合法事件的情況,導(dǎo)致算法無法正確處理。為了解決這個問題,她在代碼中增加了異常處理機(jī)制,對不合法事件進(jìn)行了過濾和忽略。

另外,她還發(fā)現(xiàn)有時在轉(zhuǎn)換規(guī)則中存在冗余的狀態(tài)轉(zhuǎn)換關(guān)系。這些冗余的關(guān)系會導(dǎo)致算法的性能下降。為了解決這個問題,她對轉(zhuǎn)換規(guī)則進(jìn)行了優(yōu)化,去除了冗余的狀態(tài)轉(zhuǎn)換關(guān)系。

在這個過程中,小欣也加入了她的研究。小欣的專業(yè)是計算機(jī)網(wǎng)絡(luò),對TCP/IP協(xié)議有深入的了解。她的加入為小悅的研究帶來了新的視角和想法。她們共同研究、探討,不斷優(yōu)化、測試和完善算法。每當(dāng)小欣看到小悅沉浸在研究中時,總會笑著說:“小悅啊,你還真是找到了你的另一半啊?!?小悅也會笑著回應(yīng):“是啊,我對計算機(jī)情有獨(dú)鐘。”

最終,經(jīng)過反復(fù)的測試和優(yōu)化,小悅和小欣成功地實現(xiàn)了TCP/IP有限狀態(tài)機(jī)模擬算法。該算法能夠準(zhǔn)確地跟蹤TCP連接的狀態(tài),并根據(jù)傳入的事件列表觸發(fā)狀態(tài)的轉(zhuǎn)換。


?算法實現(xiàn)1:

 1 public static string TraverseStates(string[] r)
 2 {
 3     // 定義一個名為tome的字典,用于存儲狀態(tài)轉(zhuǎn)換規(guī)則
 4     var tome = new Dictionary<string,Dictionary<string,string>>()
 5     {
 6         // 初始化狀態(tài)轉(zhuǎn)換規(guī)則
 7         {"CLOSED",new Dictionary<string,string>(){{"APP_PASSIVE_OPEN","LISTEN"},{"APP_ACTIVE_OPEN","SYN_SENT"}}},
 8         {"LISTEN",new Dictionary<string,string>(){{"RCV_SYN","SYN_RCVD"},{"APP_SEND","SYN_SENT"},{"APP_CLOSE","CLOSED"}}},
 9         {"SYN_SENT",new Dictionary<string,string>(){{"RCV_SYN","SYN_RCVD"},{"RCV_SYN_ACK","ESTABLISHED"},{"APP_CLOSE","CLOSED"}}},
10         {"SYN_RCVD",new Dictionary<string,string>(){{"APP_CLOSE","FIN_WAIT_1"},{"RCV_ACK","ESTABLISHED"}}},
11         {"ESTABLISHED",new Dictionary<string,string>(){{"APP_CLOSE","FIN_WAIT_1"},{"RCV_FIN","CLOSE_WAIT"}}},
12         {"CLOSE_WAIT",new Dictionary<string,string>(){{"APP_CLOSE","LAST_ACK"}}},
13         {"LAST_ACK",new Dictionary<string,string>(){{"RCV_ACK","CLOSED"}}},
14         {"FIN_WAIT_1",new Dictionary<string,string>(){{"RCV_FIN","CLOSING"},{"RCV_FIN_ACK","TIME_WAIT"},{"RCV_ACK","FIN_WAIT_2"}}},
15         {"FIN_WAIT_2",new Dictionary<string,string>(){{"RCV_FIN","TIME_WAIT"}}},
16         {"CLOSING",new Dictionary<string,string>(){{"RCV_ACK","TIME_WAIT"}}},
17         {"TIME_WAIT",new Dictionary<string,string>(){{"APP_TIMEOUT","CLOSED"}}}
18     };
19     // 初始化狀態(tài)為"CLOSED"
20     var state = "CLOSED";
21     // 遍歷輸入的字符串?dāng)?shù)組
22     foreach (var s in r){
23         // 如果當(dāng)前狀態(tài)對應(yīng)的字典包含當(dāng)前輸入字符串,則更新狀態(tài)為對應(yīng)的新狀態(tài)
24         if (tome[state].ContainsKey(s)){state = tome[state][s];}
25         // 如果當(dāng)前狀態(tài)對應(yīng)的字典不包含當(dāng)前輸入字符串,則返回"ERROR"
26         else {return "ERROR";}
27     }
28     // 返回最終的狀態(tài)
29     return state;
30 }

這段代碼是一個簡單的TCP/IP狀態(tài)機(jī)實現(xiàn),它模擬了TCP連接的建立和關(guān)閉過程。這個狀態(tài)機(jī)算法是基于有限狀態(tài)機(jī)(Finite State Machine,F(xiàn)SM)的概念實現(xiàn)的。FSM 是一種數(shù)學(xué)模型,用于描述一些具有離散狀態(tài)的系統(tǒng),這些系統(tǒng)在接收輸入時會發(fā)生狀態(tài)轉(zhuǎn)換。FSM 還可以用于模擬計算機(jī)程序、電路設(shè)計、自動控制系統(tǒng)等方面。

在這個狀態(tài)機(jī)算法中,我們使用了一種稱為“狀態(tài)轉(zhuǎn)換表”的數(shù)據(jù)結(jié)構(gòu)來描述狀態(tài)之間的轉(zhuǎn)換關(guān)系。狀態(tài)轉(zhuǎn)換表是一個二維表格,其中每一行代表一個狀態(tài),每一列代表一個輸入事件,每個單元格包含了從當(dāng)前狀態(tài)接收到某個輸入事件后應(yīng)該轉(zhuǎn)換到的下一個狀態(tài)。

下面是一個簡單的狀態(tài)轉(zhuǎn)換圖,展示了從 "CLOSED" 狀態(tài)開始,經(jīng)過一系列輸入事件后可能到達(dá)的各個狀態(tài):

              +------------+      RCV_SYN       +------------+
              |   CLOSED   |--------------------|  SYN_RCVD  |
              +------------+                    +------------+
                    | APP_ACTIVE_OPEN                 |
                    |                                 |
                    |                                 |
              RCV_SYN_ACK                       RCV_ACK
                    |                                 |
                    |                                 |
                    v                                 v
              +------------+                    +------------+
              |  SYN_SENT  |--------------------| ESTABLISHED|
              +------------+      RCV_FIN       +------------+
                    | RCV_SYN_ACK |         | RCV_FIN_ACK |
                    |             |         |             |
                    |             v         |             v
                    |       +------------+ |       +------------+
                    +-------| FIN_WAIT_1 | |-------| FIN_WAIT_2 |
                            +------------+         +------------+
                    RCV_FIN |         | RCV_FIN |         | RCV_FIN
                            |         v         |         v
                            |   +------------+ |   +------------+
                            +---|  CLOSING   | |---| TIME_WAIT |
                                +------------+     +------------+
                                      RCV_ACK           | APP_TIMEOUT
                                                        |
                                                        v
                                                  +------------+
                                                  |   CLOSED   |
                                                  +------------+

在這個狀態(tài)轉(zhuǎn)換圖中,每個圓圈代表一個狀態(tài),每個箭頭代表一個輸入事件或狀態(tài)轉(zhuǎn)換。例如,從 "CLOSED" 狀態(tài)開始,如果接收到 "APP_ACTIVE_OPEN" 輸入事件,狀態(tài)將會轉(zhuǎn)換到 "SYN_SENT" 狀態(tài)。如果在 "SYN_SENT" 狀態(tài)接收到 "RCV_SYN_ACK" 輸入事件,狀態(tài)將會轉(zhuǎn)換到 "ESTABLISHED" 狀態(tài)。

TCP(Transmission Control Protocol)是互聯(lián)網(wǎng)中最重要的協(xié)議之一,它是由美國國防部高級研究計劃局(ARPA)在20世紀(jì)70年代末和80年代初開發(fā)的。TCP協(xié)議的設(shè)計者是Vinton Cerf和Bob Kahn等人,他們在設(shè)計TCP時面臨了許多挑戰(zhàn),包括數(shù)據(jù)包丟失、網(wǎng)絡(luò)擁塞、數(shù)據(jù)傳輸?shù)目煽啃缘葐栴}。由于他們在TCP/IP網(wǎng)絡(luò)協(xié)議方面作出的杰出貢獻(xiàn),他們獲得了2004年的圖靈獎。

在TCP協(xié)議的設(shè)計過程中,狀態(tài)機(jī)起到了非常重要的作用。通過狀態(tài)機(jī),TCP協(xié)議可以清晰地定義連接的不同狀態(tài)(如CLOSED、LISTEN、SYN_SENT等),以及在不同狀態(tài)下接收到不同事件時的狀態(tài)轉(zhuǎn)換規(guī)則。這種設(shè)計使得TCP協(xié)議能夠在復(fù)雜的網(wǎng)絡(luò)環(huán)境下實現(xiàn)可靠的數(shù)據(jù)傳輸和連接管理。

使用測試用例 TCP.TraverseStates(new[] { "APP_PASSIVE_OPEN", "RCV_SYN", "RCV_ACK", "APP_CLOSE" }),我們可以解釋算法1實現(xiàn)TCP/IP狀態(tài)機(jī)的狀態(tài)跳轉(zhuǎn)過程:

  1. 首先,定義了一個名為tome的字典,其中包含了每個狀態(tài)對應(yīng)的可能事件以及狀態(tài)轉(zhuǎn)換規(guī)則。

  2. 初始化狀態(tài)為"CLOSED"。

  3. 接下來,遍歷輸入的字符串?dāng)?shù)組。對于每個輸入的字符串,算法會檢查當(dāng)前狀態(tài)對應(yīng)的字典中是否包含該輸入字符串。如果包含,則更新狀態(tài)為對應(yīng)的新狀態(tài);如果不包含,則返回"ERROR"。

  4. 根據(jù)給定的測試用例 TCP.TraverseStates(new[] { "APP_PASSIVE_OPEN", "RCV_SYN", "RCV_ACK", "APP_CLOSE" }),算法將依次處理輸入的事件序列:

    • "APP_PASSIVE_OPEN":根據(jù)狀態(tài)"CLOSED"對應(yīng)的字典,更新狀態(tài)為"LISTEN"。
    • "RCV_SYN":根據(jù)狀態(tài)"LISTEN"對應(yīng)的字典,更新狀態(tài)為"SYN_RCVD"。
    • "RCV_ACK":根據(jù)狀態(tài)"SYN_RCVD"對應(yīng)的字典,更新狀態(tài)為"ESTABLISHED"。
    • "APP_CLOSE":根據(jù)狀態(tài)"ESTABLISHED"對應(yīng)的字典,更新狀態(tài)為"FIN_WAIT_1"。
  5. 最終返回狀態(tài)"FIN_WAIT_1"作為輸出。


?了解了狀態(tài)跳轉(zhuǎn)的基本原理后,可以給算法1加入委托事件,這樣的狀態(tài)機(jī)就有一定的實用價值了,示例代碼:

 1 using System;
 2 using System.Collections.Generic;
 3 
 4 public delegate void StateChangedEventHandler(string newState);
 5 
 6 public static string TraverseStates(string[] r, Dictionary<string, Dictionary<string, (string newState, Action eventAction)>> stateMap, StateChangedEventHandler stateChangedEvent)
 7 {
 8     var state = "CLOSED";
 9     foreach (var s in r)
10     {
11         if (stateMap.ContainsKey(state) && stateMap[state].ContainsKey(s))
12         {
13             state = stateMap[state][s].newState;
14             stateChangedEvent?.Invoke(state); // 觸發(fā)狀態(tài)改變事件
15             stateMap[state][s].eventAction?.Invoke(); // 調(diào)用下一個狀態(tài)委托的事件
16         }
17         else
18         {
19             return "ERROR";
20         }
21     }
22     return state;
23 }
24 
25 public static void Main()
26 {
27     var stateMap = new Dictionary<string, Dictionary<string, (string newState, Action eventAction)>>()
28     {
29         // 初始化狀態(tài)轉(zhuǎn)換規(guī)則及委托事件定義
30         {"CLOSED",new Dictionary<string, (string, Action)>(){{"APP_PASSIVE_OPEN",("LISTEN", null)},{"APP_ACTIVE_OPEN",("SYN_SENT", null)}}},
31         {"LISTEN",new Dictionary<string, (string, Action)>(){{"RCV_SYN",("SYN_RCVD", null)},{"APP_SEND",("SYN_SENT", null)},{"APP_CLOSE",("CLOSED", null)}}},
32         {"SYN_SENT",new Dictionary<string, (string, Action)>(){{"RCV_SYN",("SYN_RCVD", null)},{"RCV_SYN_ACK",("ESTABLISHED", null)},{"APP_CLOSE",("CLOSED", null)}}},
33         // 其他狀態(tài)的轉(zhuǎn)換規(guī)則...
34     };
35     
36     StateChangedEventHandler stateChangedEvent = (newState) => {
37         Console.WriteLine($"State changed to {newState}");
38     };
39 
40     string[] input = {"APP_ACTIVE_OPEN", "RCV_SYN_ACK", "APP_CLOSE"};
41     var finalState = TraverseStates(input, stateMap, stateChangedEvent);
42     Console.WriteLine($"Final state: {finalState}");
43 }

?算法實現(xiàn)2:

  1     public static string TraverseStates(string[] events)
  2     {
  3         //TraverseStates 方法接收一個字符串?dāng)?shù)組 events,表示 TCP 協(xié)議中的事件序列。首先創(chuàng)建一個 StateMachineBuilder 對象,并調(diào)用 SetInitialState 和 SetErrorState 方法設(shè)置初始狀態(tài)和錯誤狀態(tài)。然后通過調(diào)用 AddState 方法添加每個狀態(tài),并使用 AddTransition 方法添加每個狀態(tài)的轉(zhuǎn)換規(guī)則。最后調(diào)用 Build 方法生成一個完整的狀態(tài)機(jī)對象。接著使用 foreach 循環(huán)遍歷事件序列,對每個事件調(diào)用 Process 方法進(jìn)行狀態(tài)轉(zhuǎn)換,并更新當(dāng)前狀態(tài)。最終返回最后一個狀態(tài)的名稱。
  4         var fsm = new StateMachineBuilder()
  5           .SetInitialState("CLOSED")
  6           .SetErrorState("ERROR")
  7           .AddState("ERROR")
  8               .Back()
  9           .AddState("CLOSED")
 10               .AddTransition("APP_PASSIVE_OPEN", "LISTEN")
 11               .AddTransition("APP_ACTIVE_OPEN", "SYN_SENT")
 12               .Back()
 13           .AddState("LISTEN")
 14               .AddTransition("RCV_SYN", "SYN_RCVD")
 15               .AddTransition("APP_SEND", "SYN_SENT")
 16               .AddTransition("APP_CLOSE", "CLOSED")
 17               .Back()
 18           .AddState("SYN_RCVD")
 19               .AddTransition("APP_CLOSE", "FIN_WAIT_1")
 20               .AddTransition("RCV_ACK", "ESTABLISHED")
 21               .Back()
 22           .AddState("SYN_SENT")
 23               .AddTransition("RCV_SYN", "SYN_RCVD")
 24               .AddTransition("RCV_SYN_ACK", "ESTABLISHED")
 25               .AddTransition("APP_CLOSE", "CLOSED")
 26               .Back()
 27           .AddState("ESTABLISHED")
 28               .AddTransition("APP_CLOSE", "FIN_WAIT_1")
 29               .AddTransition("RCV_FIN", "CLOSE_WAIT")
 30               .Back()
 31           .AddState("FIN_WAIT_1")
 32               .AddTransition("RCV_FIN", "CLOSING")
 33               .AddTransition("RCV_FIN_ACK", "TIME_WAIT")
 34               .AddTransition("RCV_ACK", "FIN_WAIT_2")
 35               .Back()
 36           .AddState("CLOSING")
 37               .AddTransition("RCV_ACK", "TIME_WAIT")
 38               .Back()
 39           .AddState("FIN_WAIT_2")
 40               .AddTransition("RCV_FIN", "TIME_WAIT")
 41               .Back()
 42           .AddState("TIME_WAIT")
 43               .AddTransition("APP_TIMEOUT", "CLOSED")
 44               .Back()
 45           .AddState("CLOSE_WAIT")
 46               .AddTransition("APP_CLOSE", "LAST_ACK")
 47               .Back()
 48           .AddState("LAST_ACK")
 49               .AddTransition("RCV_ACK", "CLOSED")
 50               .Back()
 51           .Build();
 52       
 53         var nextState = string.Empty;
 54       
 55         foreach (var @event in events) 
 56         {
 57             nextState = fsm.Process(@event);
 58         }
 59       
 60         return nextState;
 61     }
 62   
 63     //在 StateMachineBuilder 類中,使用 Dictionary 存儲所有狀態(tài)的 StateBuilder 對象,用于后續(xù)構(gòu)建狀態(tài)轉(zhuǎn)換規(guī)則。通過調(diào)用 AddState 方法添加每個狀態(tài),并使用 SetInitialState 和 SetErrorState 方法設(shè)置初始狀態(tài)和錯誤狀態(tài)。最后通過調(diào)用 Build 方法將所有狀態(tài)轉(zhuǎn)換規(guī)則組裝成一個完整的狀態(tài)機(jī)對象。
 64     class StateMachineBuilder
 65     {
 66         private readonly Dictionary<string, StateBuilder> states;
 67         private string initialState = null;
 68         private string errorState = null;
 69       
 70         public StateMachineBuilder()
 71         {
 72             states = new Dictionary<string, StateBuilder>();
 73         }
 74       
 75         public StateBuilder AddState(string name)
 76         {
 77             var state = new StateBuilder(this, name);
 78             this.states.Add(name, state);
 79             return state;
 80         }
 81       
 82         public StateMachineBuilder SetInitialState(string state)
 83         {
 84             this.initialState = state;
 85             return this;
 86         }
 87       
 88         public StateMachineBuilder SetErrorState(string state)
 89         {
 90             this.errorState = state;
 91             return this;
 92         }
 93       
 94         public StateMachine Build() 
 95         {
 96             var states = this.states.Values.Select(state => state.Build()).ToDictionary(state => state.Name);
 97             var errorState = states[this.errorState];
 98             var initialState = states[this.initialState];
 99             return new StateMachine(states, initialState, errorState);
100         }
101     }
102   
103     //在 StateBuilder 類中,使用 Dictionary 存儲當(dāng)前狀態(tài)的所有轉(zhuǎn)換規(guī)則。通過調(diào)用 AddTransition 方法添加每個轉(zhuǎn)換規(guī)則。通過調(diào)用 Back 方法返回上一級的 StateMachineBuilder 對象,并通過調(diào)用 Build 方法生成當(dāng)前狀態(tài)的 State 對象。
104     class StateBuilder 
105     {
106         private readonly Dictionary<string, string> transitions;
107         private readonly StateMachineBuilder parent;
108         private readonly string name;
109       
110         public StateBuilder(StateMachineBuilder parent, string name)
111         {
112             this.parent = parent;
113             this.name = name;
114             this.transitions = new Dictionary<string, string>();
115         }
116       
117         public StateBuilder AddTransition(string @event, string nextState)
118         {
119             this.transitions.Add(@event, nextState);
120             return this;
121         }
122       
123         public StateMachineBuilder Back() => this.parent;
124         public State Build() => new State(this.name, this.transitions);
125     }
126   
127     //在 StateMachine 類中,使用 Dictionary 存儲所有狀態(tài)的 State 對象,用于后續(xù)狀態(tài)轉(zhuǎn)換。通過調(diào)用 Process 方法進(jìn)行狀態(tài)轉(zhuǎn)換,并更新當(dāng)前狀態(tài)。如果當(dāng)前狀態(tài)的轉(zhuǎn)換規(guī)則中不包含當(dāng)前事件,則返回錯誤狀態(tài)的名稱。
128     class StateMachine
129     {
130         private readonly Dictionary<string, State> states;
131         private State currentState;
132         private State errorState;
133       
134         public StateMachine(Dictionary<string, State> states, State initialState, State errorState)
135         {
136             this.states = states;
137             this.currentState = initialState;
138             this.errorState = errorState;
139         }
140       
141         public string Process(string @event)
142         {
143             this.currentState = this.states[this.currentState.Process(@event)];
144             return this.currentState.Name;
145         }
146     }
147   
148     //在 State 類中,存儲當(dāng)前狀態(tài)的名稱和所有轉(zhuǎn)換規(guī)則。通過調(diào)用 Process 方法處理當(dāng)前事件,并返回下一個狀態(tài)的名稱。如果當(dāng)前狀態(tài)的轉(zhuǎn)換規(guī)則中不包含當(dāng)前事件,則返回錯誤狀態(tài)的名稱。
149     class State 
150     {
151         private readonly Dictionary<string, string> transitions;
152         public string Name { get; private set; }
153       
154         public State(string name, Dictionary<string, string> transitions) 
155         {
156             this.Name = name;
157             this.transitions = transitions;
158         }
159       
160         public string Process(string @event)
161         {
162             if (!this.transitions.TryGetValue(@event, out var nextState)) 
163             {
164                 return "ERROR";
165             }
166           
167             return nextState;
168         }
169     }

算法2實現(xiàn)了一個有限狀態(tài)機(jī),用于模擬 TCP 協(xié)議的狀態(tài)轉(zhuǎn)換過程。具體實現(xiàn)方式是使用了建造者模式,將狀態(tài)機(jī)的構(gòu)建過程分解為多個步驟,每個步驟對應(yīng)一個建造者對象,最終通過調(diào)用?Build()?方法將所有建造者對象組裝成一個完整的狀態(tài)機(jī)對象。

在這個有限狀態(tài)機(jī)中,狀態(tài)被抽象為一個名為?State?的類,包含狀態(tài)名稱和狀態(tài)轉(zhuǎn)換規(guī)則(即從當(dāng)前狀態(tài)處理某個事件后,轉(zhuǎn)換到下一個狀態(tài)的規(guī)則)。狀態(tài)機(jī)被抽象為一個名為?StateMachine?的類,包含當(dāng)前狀態(tài)、錯誤狀態(tài)和狀態(tài)轉(zhuǎn)換方法。建造者對象被抽象為一個名為?StateMachineBuilder?的類,包含多個?StateBuilder?對象,用于構(gòu)建每個狀態(tài)的轉(zhuǎn)換規(guī)則。


算法1(直接實現(xiàn))的優(yōu)點(diǎn):

  1. 直接實現(xiàn)狀態(tài)機(jī)的構(gòu)建和狀態(tài)轉(zhuǎn)換邏輯,代碼相對簡單直接,適用于簡單的狀態(tài)機(jī)。
  2. 不需要引入額外的設(shè)計模式,代碼結(jié)構(gòu)相對簡單,易于理解和上手。

算法1的缺點(diǎn):

  1. 對于復(fù)雜的狀態(tài)機(jī),直接實現(xiàn)可能會使得代碼結(jié)構(gòu)變得混亂,不易維護(hù)和擴(kuò)展。
  2. 可能會將狀態(tài)機(jī)的構(gòu)建邏輯和狀態(tài)轉(zhuǎn)換邏輯耦合在一起,不利于代碼的分層和模塊化。

算法2(建造者模式)的優(yōu)點(diǎn):

  1. 可以將狀態(tài)機(jī)的構(gòu)建過程分解為多個步驟,每個步驟對應(yīng)一個建造者對象,使得構(gòu)建過程更加靈活和可控。
  2. 通過建造者模式將狀態(tài)機(jī)的構(gòu)建過程與表示分離,使得代碼結(jié)構(gòu)更加清晰,易于維護(hù)和擴(kuò)展。
  3. 可以在建造者對象中進(jìn)行狀態(tài)轉(zhuǎn)換規(guī)則的設(shè)置,使得狀態(tài)機(jī)的構(gòu)建過程更加模塊化和可復(fù)用。

算法2的缺點(diǎn):

  1. 建造者模式引入了多個建造者對象,增加了代碼的復(fù)雜度,可能會使得代碼量增加。
  2. 對于簡單的狀態(tài)機(jī),引入建造者模式可能會顯得過于繁瑣和復(fù)雜。

以實際應(yīng)用場景說明:假設(shè)我們有一個復(fù)雜的自動駕駛系統(tǒng),其中包含了多種車輛狀態(tài)(行駛中、停車中、充電中、故障中等),以及各種復(fù)雜的狀態(tài)轉(zhuǎn)換規(guī)則(例如在行駛中狀態(tài)下,如果檢測到障礙物需要切換到停車狀態(tài),然后根據(jù)充電狀態(tài)和電量情況決定是否前往充電站等)。在這種情況下,如果用算法1直接實現(xiàn)狀態(tài)機(jī)的邏輯,可能會將所有狀態(tài)和狀態(tài)轉(zhuǎn)換規(guī)則耦合在一起,導(dǎo)致代碼結(jié)構(gòu)變得混亂,不易維護(hù)和擴(kuò)展。這種場景適合使用算法2。


?測試用例:

 1 using NUnit.Framework;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 
 6 public class SolutionTest
 7 {
 8 
 9     [Test]
10     public void FixedTests()
11     {
12         Assert.AreEqual("FIN_WAIT_1", TCP.TraverseStates(new[] { "APP_PASSIVE_OPEN", "RCV_SYN", "RCV_ACK", "APP_CLOSE" }));
13         Assert.AreEqual("ESTABLISHED", TCP.TraverseStates(new[] { "APP_PASSIVE_OPEN", "RCV_SYN", "RCV_ACK" }));
14         Assert.AreEqual("SYN_RCVD", TCP.TraverseStates(new[] { "APP_PASSIVE_OPEN", "RCV_SYN" }));
15         Assert.AreEqual("LISTEN", TCP.TraverseStates(new[] { "APP_PASSIVE_OPEN" }));
16         Assert.AreEqual("CLOSED", TCP.TraverseStates(new[] { "APP_ACTIVE_OPEN", "APP_CLOSE" }));
17         Assert.AreEqual("TIME_WAIT", TCP.TraverseStates(new[] { "APP_ACTIVE_OPEN", "RCV_SYN", "APP_CLOSE", "RCV_FIN", "RCV_ACK" }));
18         Assert.AreEqual("CLOSED", TCP.TraverseStates(new[] { "APP_ACTIVE_OPEN", "RCV_SYN", "APP_CLOSE", "RCV_FIN", "RCV_ACK", "APP_TIMEOUT" }));
19         Assert.AreEqual("ERROR", TCP.TraverseStates(new[] { "RCV_SYN", "RCV_ACK", "APP_CLOSE" }));
20         Assert.AreEqual("FIN_WAIT_2", TCP.TraverseStates(new[] { "APP_ACTIVE_OPEN", "RCV_SYN", "APP_CLOSE", "RCV_ACK" }));
21         Assert.AreEqual("CLOSE_WAIT", TCP.TraverseStates(new[] { "APP_ACTIVE_OPEN", "RCV_SYN_ACK", "RCV_FIN" }));
22         Assert.AreEqual("LAST_ACK", TCP.TraverseStates(new[] { "APP_ACTIVE_OPEN", "RCV_SYN_ACK", "RCV_FIN", "APP_CLOSE" }));
23         Assert.AreEqual("SYN_SENT", TCP.TraverseStates(new[] { "APP_ACTIVE_OPEN" }));
24         Assert.AreEqual("CLOSED", TCP.TraverseStates(new[] { "APP_PASSIVE_OPEN", "APP_CLOSE" }));
25         Assert.AreEqual("FIN_WAIT_1", TCP.TraverseStates(new[] { "APP_ACTIVE_OPEN", "RCV_SYN_ACK", "APP_CLOSE" }));
26         Assert.AreEqual("ERROR", TCP.TraverseStates(new[] { "APP_PASSIVE_OPEN", "RCV_SYN", "RCV_ACK", "APP_PASSIVE_OPEN" }));
27         Assert.AreEqual("TIME_WAIT", TCP.TraverseStates(new[] { "APP_PASSIVE_OPEN", "RCV_SYN", "RCV_ACK", "APP_CLOSE", "RCV_FIN_ACK", "APP_TIMEOUT", "APP_ACTIVE_OPEN", "RCV_SYN", "APP_CLOSE", "RCV_FIN", "RCV_ACK" }));
28         Assert.AreEqual("ERROR", TCP.TraverseStates(new[] { "APP_PASSIVE_OPEN", "RCV_SYN", "RCV_ACK", "APP_CLOSE", "RCV_SYN" }));
29         Assert.AreEqual("ERROR", TCP.TraverseStates(new[] { "APP_PASSIVE_OPEN", "APP_CLOSE", "RCV_SYN" }));
30         Assert.AreEqual("FIN_WAIT_1", TCP.TraverseStates(new[] { "APP_PASSIVE_OPEN", "RCV_SYN", "RCV_ACK", "APP_CLOSE" }));
31         Assert.AreEqual("CLOSING", TCP.TraverseStates(new[] { "APP_PASSIVE_OPEN", "RCV_SYN", "RCV_ACK", "APP_CLOSE", "RCV_FIN" }));
32     }
33 
34     //------------------------------------------
35 
36     private static string[] ALL_CMDS = "APP_PASSIVE_OPEN, APP_ACTIVE_OPEN, APP_SEND, APP_CLOSE, APP_TIMEOUT, RCV_SYN, RCV_ACK, RCV_SYN_ACK, RCV_FIN, RCV_FIN_ACK".Split(", ");
37 
38     private static string START = "CLOSED", ERROR = "ERROR";
39 
40     private static Dictionary<string, Dictionary<string, string>> STATES = new Dictionary<string, Dictionary<string, string>>()
41     {
42         ["CLOSED"] = new Dictionary<string, string> { ["APP_PASSIVE_OPEN"] = "LISTEN", ["APP_ACTIVE_OPEN"] = "SYN_SENT" },
43         ["LISTEN"] = new Dictionary<string, string> { ["RCV_SYN"] = "SYN_RCVD", ["APP_SEND"] = "SYN_SENT", ["APP_CLOSE"] = "CLOSED" },
44         ["SYN_RCVD"] = new Dictionary<string, string> { ["APP_CLOSE"] = "FIN_WAIT_1", ["RCV_ACK"] = "ESTABLISHED" },
45         ["SYN_SENT"] = new Dictionary<string, string> { ["RCV_SYN"] = "SYN_RCVD", ["RCV_SYN_ACK"] = "ESTABLISHED", ["APP_CLOSE"] = "CLOSED" },
46         ["ESTABLISHED"] = new Dictionary<string, string> { ["APP_CLOSE"] = "FIN_WAIT_1", ["RCV_FIN"] = "CLOSE_WAIT" },
47         ["FIN_WAIT_1"] = new Dictionary<string, string> { ["RCV_FIN"] = "CLOSING", ["RCV_FIN_ACK"] = "TIME_WAIT", ["RCV_ACK"] = "FIN_WAIT_2" },
48         ["CLOSING"] = new Dictionary<string, string> { ["RCV_ACK"] = "TIME_WAIT" },
49         ["FIN_WAIT_2"] = new Dictionary<string, string> { ["RCV_FIN"] = "TIME_WAIT" },
50         ["TIME_WAIT"] = new Dictionary<string, string> { ["APP_TIMEOUT"] = "CLOSED" },
51         ["CLOSE_WAIT"] = new Dictionary<string, string> { ["APP_CLOSE"] = "LAST_ACK" },
52         ["LAST_ACK"] = new Dictionary<string, string> { ["RCV_ACK"] = "CLOSED" }
53     };
54 
55     private Random rnd = new Random();
56     private int Rand(int a, int b) => a + rnd.Next(b - a);
57     private int Rand(int a) => rnd.Next(a);
58     private string Choice(string[] stuff) => stuff[Rand(stuff.Length)];
59     private string[] GetCmdsOf(string state) => STATES[state].Keys.ToArray();
60 
61     [Test]
62     public void RandomTests()
63     {
64         DoTests(100, 2, 5, 79);
65         DoTests(100, 10, 51, 97);
66     }
67 
68     private void DoTests(int nTests, int nCmdMin, int nCmdMax, int endProba)
69     {
70         for (int n = 0; n < nTests; n++)
71         {
72             string state = START, last = null;
73             var cmds = new List<string>();
74             var x = Rand(nCmdMin, nCmdMax);
75 
76             for (int i = 0; i < x; i++)
77             {
78                 var endIt = Rand(0, 100) > endProba;
79                 last = Choice(endIt ? ALL_CMDS : GetCmdsOf(state));
80                 state = STATES[state].GetValueOrDefault(last, ERROR);
81                 cmds.Add(last);
82                 if (endIt) break;
83             }
84             Assert.AreEqual(state, TCP.TraverseStates(cmds.ToArray()));
85         }
86     }
87 }

?RandomTests()是一個隨機(jī)測試算法,它使用了隨機(jī)數(shù)生成器來執(zhí)行一系列測試。在代碼中,定義了一些輔助方法來生成隨機(jī)數(shù)和隨機(jī)選擇數(shù)組中的元素。在RandomTests方法中,調(diào)用了DoTests方法來執(zhí)行一定數(shù)量的測試。DoTests方法中,使用循環(huán)生成隨機(jī)數(shù)量的命令,并根據(jù)狀態(tài)轉(zhuǎn)移表來更新狀態(tài),并將命令添加到列表中。最后,使用斷言來驗證狀態(tài)轉(zhuǎn)移的正確性。整體來說,這段代碼利用隨機(jī)性來執(zhí)行測試,以發(fā)現(xiàn)潛在的問題和錯誤。

隨機(jī)測試的概念在軟件工程和計算機(jī)科學(xué)領(lǐng)域中已經(jīng)存在了很長時間。早期的軟件測試主要集中在手動編寫測試用例和靜態(tài)分析上,但是隨著軟件規(guī)模的增長和復(fù)雜性的提高,傳統(tǒng)的測試方法變得不夠高效。

隨機(jī)測試的概念是在20世紀(jì)70年代提出的,最初用于測試編譯器和解釋器。隨機(jī)測試的理念是利用隨機(jī)性來生成測試用例,以期望發(fā)現(xiàn)一些邊緣情況和異常行為,從而提高軟件的質(zhì)量和穩(wěn)定性。隨機(jī)測試方法在軟件測試領(lǐng)域中得到了廣泛的應(yīng)用,特別是在開源軟件和大型系統(tǒng)中。

隨機(jī)測試的方法和技術(shù)也在不斷發(fā)展和演進(jìn),包括基于模型的隨機(jī)測試、符號執(zhí)行、模糊測試等。隨機(jī)測試已經(jīng)成為了軟件測試領(lǐng)域中重要的一種測試方法,對于發(fā)現(xiàn)軟件中的潛在問題和錯誤具有重要作用。文章來源地址http://www.zghlxwxcb.cn/news/detail-747112.html

到了這里,關(guān)于【算法】狀態(tài)之美,TCP/IP狀態(tài)轉(zhuǎn)換探索的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • TCP狀態(tài)轉(zhuǎn)換圖

    TCP狀態(tài)轉(zhuǎn)換圖

    TCP狀態(tài)轉(zhuǎn)換圖 了解TCP狀態(tài)轉(zhuǎn)換圖可以幫助開發(fā)人員查找問題. 說明: 上圖中粗線表示主動方, 虛線表示被動方, 細(xì)線部分表示一些特殊情況, 了解即可, 不必深入研究. 對于建立連接的過程客戶端屬于主動方, 服務(wù)端屬于被動接受方(圖的上半部分) 而對于關(guān)閉(圖的下半部分), 服務(wù)

    2024年02月15日
    瀏覽(21)
  • TCP的四次揮手與TCP狀態(tài)轉(zhuǎn)換

    TCP的四次揮手與TCP狀態(tài)轉(zhuǎn)換

    TCP客戶端與服務(wù)器斷開連接的時候,在程序中使用close()函數(shù),會使用TCP協(xié)議四次揮手。 客戶端和服務(wù)端都可以主動發(fā)起。 因TCP連接時候是雙向的,所以斷開的時候也是雙向的。 三次揮手可以嗎?可以是可以,和狀態(tài)有關(guān)。 四次揮手是用于客戶端和服務(wù)器斷開連接的時候,

    2024年02月13日
    瀏覽(15)
  • Linux網(wǎng)絡(luò)編程(TCP狀態(tài)轉(zhuǎn)換關(guān)系)

    Linux網(wǎng)絡(luò)編程(TCP狀態(tài)轉(zhuǎn)換關(guān)系)

    本篇文章來講解一下TCP的狀態(tài)轉(zhuǎn)換關(guān)系,學(xué)習(xí)這個狀態(tài)轉(zhuǎn)換關(guān)系對于我們深入了解網(wǎng)絡(luò)編程是非常有必要的。 客戶端狀態(tài)轉(zhuǎn)換: 1.CLOSED - SYN-SENT:當(dāng)客戶端嘗試與服務(wù)器建立連接時,客戶端從CLOSED狀態(tài)轉(zhuǎn)換到SYN-SEND狀態(tài)。此時客戶端發(fā)送SYN(同步)包,表示請求建立連接,并

    2024年02月07日
    瀏覽(19)
  • TCP通訊(三次握手、四次揮手;滑動窗口;TCP狀態(tài)轉(zhuǎn)換;端口復(fù)用;TCP心跳檢測機(jī)制)

    TCP通訊(三次握手、四次揮手;滑動窗口;TCP狀態(tài)轉(zhuǎn)換;端口復(fù)用;TCP心跳檢測機(jī)制)

    ?前言:建議看著圖片,根據(jù)文字描述走一遍TCP通訊過程,加深理解。 目錄 TCP通信時序: 1)建立連接(三次握手)的過程: 2)數(shù)據(jù)傳輸?shù)倪^程: 3)關(guān)閉連接(四次揮手)的過程: 滑動窗口 (TCP流量控制): TCP狀態(tài)轉(zhuǎn)換: 半關(guān)閉: 2MSL: 程序設(shè)計中的問題: 端口復(fù)用:

    2024年02月03日
    瀏覽(18)
  • 4.23 TCP狀態(tài)轉(zhuǎn)換 4.24半關(guān)閉、端口復(fù)用

    4.23 TCP狀態(tài)轉(zhuǎn)換 4.24半關(guān)閉、端口復(fù)用

    2MSL(Maximum Segment Lifetime) 主動斷開連接的一方,最后進(jìn)入一個TIME_WAIT狀態(tài),這個狀態(tài)會持續(xù):2msl msl:官方建議:2分鐘,實際是30s 當(dāng) TCP 連接主動關(guān)閉方接收到被動關(guān)閉方發(fā)送的 FIN 和最終的 ACK 后,連接的主動關(guān)閉方必須處于TIME_WAIT 狀態(tài)并持續(xù) 2MSL 時間。 這樣就能夠讓 TCP 連

    2024年02月10日
    瀏覽(16)
  • 4.23、TCP狀態(tài)轉(zhuǎn)換(為什么四次揮手)

    4.23、TCP狀態(tài)轉(zhuǎn)換(為什么四次揮手)

    2MSL(Maximum Segment Lifetime) 主動斷開連接的一方, 最后進(jìn)入一個 TIME_WAIT狀態(tài), 這個狀態(tài)會持續(xù): 2msl msl : 官方建議: 2分鐘 , 實際是 30s 當(dāng) TCP 連接主動關(guān)閉方接收到被動關(guān)閉方發(fā)送的 FIN 和最終的 ACK 后,連接的主動關(guān)閉方必須處于 TIME_WAIT 狀態(tài)并持續(xù) 2MSL 時間。 這樣就能夠讓 T

    2023年04月22日
    瀏覽(24)
  • 【網(wǎng)絡(luò)】TCP通訊(三次握手、四次揮手;滑動窗口;TCP狀態(tài)轉(zhuǎn)換;端口復(fù)用;TCP心跳檢測機(jī)制)

    【網(wǎng)絡(luò)】TCP通訊(三次握手、四次揮手;滑動窗口;TCP狀態(tài)轉(zhuǎn)換;端口復(fù)用;TCP心跳檢測機(jī)制)

    ?前言:建議看著圖片,根據(jù)文字描述走一遍TCP通訊過程,加深理解。 目錄 TCP通信時序: 1)建立連接(三次握手)的過程: 2)數(shù)據(jù)傳輸?shù)倪^程: 3)關(guān)閉連接(四次揮手)的過程: 滑動窗口 (TCP流量控制): TCP狀態(tài)轉(zhuǎn)換: 半關(guān)閉: 2MSL: 程序設(shè)計中的問題: 端口復(fù)用:

    2024年02月07日
    瀏覽(29)
  • LwIP系列(5):TCP 3次握手+4次揮手+狀態(tài)機(jī)轉(zhuǎn)換

    LwIP系列(5):TCP 3次握手+4次揮手+狀態(tài)機(jī)轉(zhuǎn)換

    TCP的3次握手、4次揮手以及TCP狀態(tài)機(jī),是TCP的核心概念,我們在分析LwIp中TCP相關(guān)代碼流程,也需要熟悉這些流程,本文就詳細(xì)介紹這些概念。 網(wǎng)上針對為什么是3次握手,會有很多的分析,尤其有些文章會特別強(qiáng)調(diào)client和server的seq序列號同步,眾說紛紜吧,我個人傾向于: 防止

    2024年02月13日
    瀏覽(75)
  • 網(wǎng)絡(luò)通信深入解析:探索TCP/IP模型

    網(wǎng)絡(luò)通信深入解析:探索TCP/IP模型

    ? ? ? ? 你知道在我們的網(wǎng)頁瀏覽器的地址當(dāng)中輸入url,未必是如何呈現(xiàn)的嗎? ? ? ? ? web瀏覽器根據(jù)地址欄中指定的url,從web服務(wù)器獲取文件資源(resource)等信息,從而顯示出web頁面。web使用HTTP(超文本傳輸協(xié)議)的協(xié)議作為規(guī)范,完成從客戶端從服務(wù)器端等一系列的運(yùn)

    2024年02月07日
    瀏覽(25)
  • TCP/IP 三次握手&四次揮手詳解,以及異常狀態(tài)分析

    1.TCP/IP 三次握手 TCP/IP 三次握手過程 主要依靠IP協(xié)議報文中的 SYN ACK 兩個標(biāo)識位,SYN 表示是請求連接的報文,ACK 表示確認(rèn)報文的請求 過程: 客戶端處于 CLOSE 狀態(tài),服務(wù)器處于 LISTEN 狀態(tài),客戶端向服務(wù)器發(fā)送請求連接報文,SYN=1 seq=x,發(fā)送成功后,客戶端狀態(tài)修改為 SYN_SEND

    2024年02月22日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包