隨着網絡的使用,目前所有大型的金融機構都已經實現了自動化和數字化。當中肯定少不了互聯網的加入,那麼在這當中,我們主要介紹一下FIX協議。它是由國際FIX協會組織提供的一個開放式協議,目的是推動國際貿易電子化的進程,在各類參與者之間,包括投資經理、經紀人,買方、賣方建立起實時的電子化通訊協議。Fix協議的目標是把各類證券金融業務需求流程格式化,使之成爲一個個可用計算機語言描述的功能流程,並在每個業務功能接口上統一交換格式,方便各個功能模塊的連接。
FIX協議結構
當前,FIX協議的格式存在着兩種結構:"標記(Tag)〉=〈值(Value)"域結構和 FIXML 結構。下面針對域結構模式對FIX協議的組成,連接建立、信息交換方法等進行簡要說明,以便於瞭解FIX協議的概念。
FIX信息格式
(1) 信息格式
一條FIX協議信息的基本格式是:
《標準頭》+《信息正文域》+《標準尾》
每條信息都是由一系列帶有〈標記(Tag)〉=〈值(Value)〉的域組成的。在每個域之間通過"< >"分開。除了一些特殊規定外,信息中的域可按照任意順序排列。所有域在都以"定界符"(#001;0x01H,文檔中寫爲<SOH>)表示終止。
(2) 標準的信息標題
每條命令或應用信息都有一個標準的標題。標題表明了信息類型、長席、目的地、序號、起始點和時間。
(3) 標準的信息尾部
所有的信息,無論是命令類的,還是應用類的,以一個標準結尾終止。尾部被用來把信息分離,幷包括含有3位數的"檢驗和"值。
(4) 數據類型
各域所使用的數據類型包括以下幾種:整數、浮點數、布爾數、字符串、多元值串、貨幣、交易所字符串域、國際標準時時間戳、國際標準時時間、本地市場日期等。
(5) 數據完整性
信息數據內容是否完整可以通過"檢查信息長度"和字符的簡單"檢驗和"兩個方法進行檢查。
(6) 加密
爲了保證信息安全,對傳遞的信息需要加密,加密方法的選擇由傳送中的有關雙方協議而定。任何域都可被加密並被添加於"密碼"的域內,不過,被確信可被清楚識別的域必須以非加密方式進行傳送,這些公開的域(非加密)能在密碼的域內被重複以完整地檢驗公開的數據。
FIX協議的連接建立
建立一個FIX連接包括:電信層面連接的創立、經由接收方對發起方的確認、信息同步三個步驟。
FIX信息交換過程的實施
FIX信息交換過程的定義爲:
在兩方之間,一個連續的序號系列範圍內的雙向定單信息傳送。每條信息都有獨特的序號識別。在每次FIX交換過程開始時,就是序號的開始,首先從1開始,並依次增加直至貫穿整個交換過程。當在FIX交換過程中重新進行連接的時候,監控序號將能使各方能識別錯過的信息,並能做出反應,來使應用方達到一致地同步。
在整個信息沒有被激活的時期裏,信息交換方將在有規則的時間間隔裏產生"心跳信息"。通過"心跳信息"可監控通信連接的狀況,識別進入的序號缺口,並確認是否接收到最後的信息串。"心跳間隔"是由交換過程發起人使用"心跳指令"域在"登錄"信息中宣佈的。
當信息交換連接的任何一方在"心跳指令"的時間內都不發送任何數據的時候,"心跳信息"將被傳送。當連接的任何一方在"心跳指令"+"合理的傳輸時間"的時間內仍沒有收到"心跳信息",那麼,可以認爲此次連接失敗,而且需開始實施修正操作。如果"心跳指令"被設置爲零,將不會生成定期的"心跳信息"。
FIX的連接註銷
信息交換過程的正常結束是通過雙方互相發送"註銷"(Logout)信息來完成。"註銷"信息是開始或確認一個FIX過程終止的信息,未經"註銷"信息的交換而斷開的連接是反常情況,並應按錯誤來處理。
FIX通信協議的應用
針對國內的證券交易模式的分佈式結構,即證券公司的各營業部、分支機構數據分佈存放,各自獨立,直接與交易所聯繫,國內券商正在探討並逐步推出集中交易系統,集中交易系統可以帶來集中風險控制、提高系統效率等優勢,可以在集中交易系統的構建、規劃過程中,借鑑應用FIX標準化協議,構建具有數據層、核心業務層+FIX通信層、應用層的廣義三層結構。用FIX金融信息交換協議包取代過去的文件或通信包交換的模式。
在FIX協議的應用過程中應該注意到,由於亞洲地區的證券交易方式與FIX協議的主導地區美洲和歐洲國家有一定的差異,因此直接利用現有的FIX協議,特別是證券業務流程上的規範有一定的困難。
例如FIX協議在日本證券行業的應用就遇到了信息定義內容和信息流程順序上的問題。因此國內的FIX的開展首先要關注FIX及其在中國的適用性,吸收其它市場的經驗,將國內外不同的交易程序加以比較,分析協議的使用方法以及協議使用環境,結合國內證券市場的實際,使得該項協議既能成爲一項標準又能爲中國證券市場服務,爲中國證券交易的標準化過程中發揮作用。
消息類型
|
序列號不必陪時的處理
|
Logon
|
必須是傳送的第一個消息。認證和接受連接。如果一個消息間隙在logon序列號中被檢測到,那麼在返回一個Logon確認消息後,發送一個ResendRequest
|
Logout
|
如果一個消息間隙被檢測到,在確認Logout消息發送之後再發起一個ResendRequest以補償所有丟失消息。不要終止會話。Logout消息的發起方負責終止會話。這樣可以允許Logout發起者對任何ResendRequest消息進行響應。
如果是Logout的發起方,那麼這是一個Logout確認消息,必須在收到之後立即終止會話。
唯一一個“不終止會話”的例外是無效的Logout嘗試。會話接收者有權發送一個Logout消息並立即終止會話。這樣可以減少未經授權的連接嘗試。
|
ResendRequest
|
首先執行重傳處理,接着按照自己的順序發送ResendRequest消息用以填充接收消息間隙。
|
SeqReset-Reset
|
忽略接收序列號。SeqReset消息的NewSeqNo將包含下一個傳送消息的序列號。
|
SeqReset-GapFill
|
發送一個返回ResendRequest。間隙填充消息行爲與SeqReset消息相似。然而,確認沒有消息被連續地跳過是非常重要的。這意味着GapFill消息必須按順序接收。一個無序的GapFill消息時則表明一種異常情況。
|
所有的其他類型消息
|
執行間隙填充操作。
|
|
SenderCompID
|
OnBehalfOfCompID
|
TartgetCompID
|
DelivrToCompID
|
A 到B
|
A
|
|
B
|
|
B 到 A
|
B
|
|
A
|
|
|
SenderCompID
|
OnBehalfOf
CompID
|
TargetCompID
|
DeliverTo
CompID
|
DeliverTo
CompID
|
HopSendingTime
|
從A通過Q到B
|
||||||
1 A到Q
|
A
|
|
Q
|
B
|
|
|
2 Q到B
|
Q
|
A
|
B
|
|
Q
|
A的發送時間
|
B通過Q響應A
|
||||||
1 B到Q
|
B
|
|
Q
|
A
|
|
|
2 Q到A
|
Q
|
B
|
A
|
|
Q
|
B的發送時間
|
A通過Q發送到B和C
|
||||||
1A到Q
|
A
|
|
Q
|
B
|
|
|
2Q到B
|
Q
|
A
|
B
|
|
Q
|
A的發送時間
|
3A到Q
|
A
|
|
Q
|
C
|
|
|
4Q到C
|
Q
|
A
|
C
|
|
Q
|
A的發送時間
|
B和C通過Q發送到A
|
||||||
1B到Q
|
B
|
|
Q
|
A
|
|
|
2Q到A
|
Q
|
B
|
A
|
|
Q
|
B的發送時間
|
3C到Q
|
C
|
|
Q
|
A
|
|
|
4Q到A
|
Q
|
C
|
A
|
|
Q
|
C的發送時間
|
Tag
(標記)
|
FieldName
(域名)
|
Req’d
(必選)
|
備註
|
|
8
|
BeginString
|
Y
|
FIXT.1.1(不能加密,必須是消息的第一個域)
|
|
9
|
BodyLength
|
Y
|
(不能加密,必須是消息的第二個域)
|
|
35
|
MsgType
|
Y
|
(不能加密,必須是消息的第三個域)
|
|
1128
|
ApplVerID
|
N
|
使用SP標示方法標明應用版本。ApplVerID用於一個特定消息的場景
|
|
1129
|
CstmApplVerID
|
N
|
用於支持客戶共同協商認可的功能
|
|
49
|
SenderCompID
|
Y
|
(不能被加密)
|
|
56
|
TargetCompID
|
Y
|
(不能被加密)
|
|
115
|
OnBehalfOfCompID
|
N
|
通過第三方發送消息時交易參與者企業ID(可以內置於堅密數據部分)
|
|
128
|
DeliverToCompID
|
N
|
通過第三方發送消息時交易參與者企業ID(可以內置於堅密數據部分)
|
|
90
|
SecureDataLen
|
N
|
用於標示消息加密部分的長度時必選(不能加密)
|
|
91
|
SecureData
|
N
|
消息體加密時必選。總緊跟在SercureDataLen域之後
|
|
34
|
MsgSeqNum
|
Y
|
(可以內置於堅密數據部分)
|
|
50
|
SenderSubID
|
N
|
(可以內置於堅密數據部分)
|
|
142
|
SenderLocationID
|
N
|
發送者的LocationID(如,地理位置和或席位(desk))(可以內置於堅密數據部分)
|
|
57
|
TargetSubID
|
N
|
爲管理消息保留,不針對一個特定用戶。(可以內置於堅密數據部分)
|
|
143
|
TargetLocationID
|
N
|
交易參與者LocationID(如,地理位置和或席位(desk))(可以內置於堅密數據部分)
|
|
116
|
OnBehalfOfSubID
|
N
|
交易參與者SubID,用於通過第三方傳送消息。(可以內置於堅密數據部分)
|
|
144
|
OnBehalfOfLocation
|
N
|
交易參與者的LocationID(如,地理位置和或席位(desk))(可以內置於堅密數據部分)
|
|
129
|
DeliverToSubID
|
N
|
交易參與者SubID,用於通過第三方傳送消息。(可以內置於堅密數據部分)
|
|
145
|
DeliverToLocationID
|
N
|
交易參與者的LocationID(如,地理位置和或席位(desk))(可以內置於堅密數據部分)
|
|
43
|
PossDupFlag
|
N
|
當重傳消息時總是必選,無論是由發送方系統提示,還是作爲重傳請求的響應結果。(可以內置於堅密數據部分)
|
|
97
|
PossResend
|
N
|
當消息可能是另一個消息的複製消息且使用一個不同的序列號時必選。(可以內置於堅密數據部分)
|
|
52
|
SendingTime
|
Y
|
(可以內置於堅密數據部分)
|
|
122
|
OrigSendingTime
|
N
|
當作爲一個ResendRequest的返回結果重傳消息時必選。如果數據不可用,則與SendingTime值相同(可以內置於堅密數據部分)
|
|
212
|
XmlDataLen
|
N
|
當標示XmlData消息體長度時必選。(可以內置於堅密數據部分)
|
|
213
|
XmlData
|
N
|
包含XML格式的消息塊(如FIXML)。總緊跟在XmlDataLen後。(可以內置於堅密數據部分)
|
|
347
|
MessageEncoding
|
N
|
在消息的“Encode”域中使用的消息編碼格式(非ASCII編碼)。使用編碼域時必選。
|
|
369
|
LastMsgSeqNumProcessed
|
N
|
FIX引擎到收到、下游應用(如交易系統、指令路由系統)處理過的的最後一個MsgSeqNum值。在每個消息發送時確定。用於參與方偵測消息積壓(未被處理?)。
|
|
627
|
NoHops
|
N
|
|
|
-〉
|
628
|
HopCompID
|
N
|
|
|
629
|
HopSendingTime
|
N
|
|
-〉
|
630
|
HopRefID
|
N
|
|
Tag
(標記)
|
FieldName
(域名)
|
Req’d
(必選)
|
備註
|
93
|
SignatureLength
|
N
|
如果尾部包含簽名則必選。注意,不能包含在SecureData域中。
|
89
|
Signature
|
N
|
注意,不能包含在SecureData域中。
|
10
|
CheckSum
|
Y
|
(不能加密,總是消息的最後一個域)
|
Tag
(標記)
|
FieldName
(域名)
|
Req’d
(必選)
|
備註
|
|
StandardHeader標準頭部
|
Y
|
MsgType=0
|
112
|
TestReqID
|
N
|
當Heartbeat消息是Test Request消息的響應時必選
|
|
StandartTrailer
|
Y
|
|
Tag
(標記)
|
FieldName
(域名)
|
Req’d
(必選)
|
備註
|
|
StandardHeader標準頭部
|
Y
|
MsgType=A
|
98
|
EncryptMethod
|
Y
|
不能加密
|
108
|
HearBtInt
|
Y
|
雙方使用同一個值
|
95
|
RawDataLength
|
N
|
由一些認證方法使用
|
96
|
RawData
|
N
|
由一些認證方法使用
|
141
|
ResetSeqNumFlag
|
N
|
表示FIX會話雙方應復位序列號
|
789
|
NextExpectedMsgSeqNum
|
N
|
可選,雙方檢測和恢復消息間隙的候選協商方法參照“Logon消息NextExpectedMsgSeqNum
”
|
383
|
MaxMessageSize
|
N
|
能用於指定所支持接收消息的最大字節數
|
384
|
NoMsgTypes
|
N
|
指定RefMsgTypes的重複次數
|
-〉
|
372 RefMsgType
|
N
|
制定一個特定的、被支持的MsgType。如果NoMsgTypes大於0時必選。從Logon消息的發送者角度應當被指定。
|
-〉
|
385 MsgDirection
|
N
|
表明所支持MsgType的接收或發送方向。當NoMsgTypes大於0時必選。從Logon消息的發送者角度應當被指定。
|
-〉
|
1130 RefApplVerID
|
N
|
在會話層指定一個消息的應用SP發行版本。SP發行時付值的枚舉域。
|
-〉
|
1131 RefCstmApplVerID
|
N
|
再會話層指定一個用戶擴展消息的應用。
|
464
|
TestMessageIndicator
|
N
|
用於指定此FIX會話將發送、接收 “Test” “production”消息。 ?
|
553
|
Username
|
N
|
|
554
|
Password
|
N
|
注意,沒有傳輸層加密時存在最小安全性。
|
1137
|
DefaultApplVerID
|
Y
|
由FIXT承載的FIX的默認版本。
|
|
StandartTrailer
|
Y
|
|
Tag
(標記)
|
FieldName
(域名)
|
Req’d
(必選)
|
備註
|
|
StandardHeader標準頭部
|
Y
|
MsgType=A
|
112
|
TestReqID
|
Y
|
不能加密
|
|
StandartTrailer
|
Y
|
|
Tag
(標記)
|
FieldName
(域名)
|
Req’d
(必選)
|
備註
|
|
StandardHeader標準頭部
|
Y
|
MsgType=2
|
7
|
BeginSeqNo
|
Y
|
不能加密
|
16
|
EndSeqNo
|
Y
|
|
|
StandartTrailer
|
Y
|
|
SessionRejectReason
|
0=Invalid tag number 無效的tag編號
|
1=Required tag missing tag丟失
|
2=Tag not defined for this message type 這類消息的Tag沒有被定義
|
3=Undefined Tag 未知Tag
|
4=Tag specified without a value 缺少Tag值
|
5=Value is incorrect (out of range) for this tag tag值錯誤(超界)
|
6=Incorrect data format for value 錯誤值數據
|
7=Decryption problem 解密錯誤
|
8=Signature problem 簽名錯誤
|
9=CompID problem 企業ID錯
|
10=SendingTime accuracy problem 發送時間不正確
|
11=Invalid MsgType 無效的MsgType
|
12=XML Validation error XML語法驗證錯誤
|
13=Tag appears more than once Tag重複出現
|
14=Tag specificed out of required order 指定的Tag順序錯誤
|
15=Repeating group fields out of order 重複組域順序錯誤
|
16=Incorrect NumInGroup count for repeating group 重複組NumInGroup錯誤
|
17=Non “data” value includes field delimiter(SOH character) 包含了SOH分界符的錯誤數據
|
99=Other 其它錯誤
|
注意:其他的會話級規則衝突可能存在,SessionRejectReason值爲99(Other),並在Text域中進行詳細描述。
|
Tag
(標記)
|
FieldName
(域名)
|
Req’d
(必選)
|
備註
|
|
StandardHeader標準頭部
|
Y
|
MsgType=3
|
45
|
RefSeqNum
|
Y
|
被駁回消息的MsgSeqNum
|
371
|
RefTagID
|
N
|
被參照的FIX域tag值
|
372
|
RefMsgType
|
N
|
被參照的FIX消息MsgType值
|
373
|
SessionRejectReason
|
N
|
會話級駁回消息錯誤代碼
|
58
|
Text
|
N
|
解釋駁回原因的文本信息
|
354
|
EncodedTextLen
|
N
|
如果使用EncodeText域,必選,且EncodeText必須緊跟在該域之後
|
355
|
EncodedText
|
N
|
使用MessageEncoding
域制定的編碼規則對Text域內容的編碼數據(非ASCII碼)
|
|
StandartTrailer
|
Y
|
|
Tag
(標記)
|
FieldName
(域名)
|
Req’d
(必選)
|
備註
|
|
StandardHeader標準頭部
|
Y
|
MsgType=4
|
123
|
GapFillFlag
|
N
|
|
36
|
NewSeqNo
|
Y
|
|
|
StandartTrailer
|
Y
|
|
Tag
(標記)
|
FieldName
(域名)
|
Req’d
(必選)
|
備註
|
|
StandardHeader標準頭部
|
Y
|
MsgType=5
|
58
|
Text
|
N
|
|
354
|
EncodedTextLen
|
N
|
如果使用EncodeText域,必選,且EncodeText必須緊跟在該域之後
|
355
|
EncodedText
|
N
|
使用MessageEncoding
域制定的編碼規則對Text域內容的編碼數據(非ASCII碼)
|
|
StandartTrailer
|
Y
|
|
Precedence
次序
|
State
狀體
|
Initiator
發起者
|
Acceptor
接收者
|
Descriptioin
描述
|
1
|
斷開 當天未連接
|
Y
|
Y
|
當前處於斷開狀態,當日未進行連接嘗試。沒有MsgSeqNum被使用(下一個當日的連接的MsgSeqNum值爲1)。
|
2
|
斷開 當日開始連接
|
Y
|
Y
|
當前處於斷開狀態,嘗試建立當日連接,這樣,MsgSeqNum開始被消耗(下一個當日連接時,MsgSeqNum將從其(last+1)開始)
|
3
|
檢測到網絡連接的中斷
|
Y
|
Y
|
處於連接狀態時,檢測到一個網絡連接中斷(如TCP socket關閉)。斷開網絡連接並關閉該會話的配置。
|
4
|
等待連接
|
N
|
Y
|
會話登陸消息接收者等待對端的連接。
|
5
|
初始話(發起)連接
|
Y
|
N
|
會話登陸消息發起者同對端建立連接。
|
6
|
網絡連接建立
|
Y
|
Y
|
雙方建立網絡連接。
|
7
|
發送Logon發起消息
|
Y
|
N
|
會話登陸發起者發送Logon
消息。
***異常:24小時會話
|
8
|
收到Logon發起消息
|
N
|
Y
|
會話登陸接收者收到對端的Logon消息
***異常:24小時會話
|
9
|
Logon發起消息響應
|
N
|
Y
|
會話登陸接收者使用Logon消息與對端握手,響應對端Logon消息。
|
10
|
處理ResendRequest
|
Y
|
Y
|
接收和響應對端發送的對消息的ResendRequeset消息,和(或)對MsgSeqNum所請求範圍的SequenceReset-Gap Fill消息。修改以駁回接收到的MsgSeqNum小於LastSeqNum的Resend Request消息。
|
11
|
收到MsgSeqNum過大
|
Y
|
Y
|
從對端接收到過大的MsgSeqNum,將消息排隊暫存,發送ResendRequest消息
|
12
|
等待/處理ResendRequest響應
|
Y
|
Y
|
處理請求的MsgSeqNum請求的、PossDupFlag=’Y’的消息,和/或從對端進行的SequenceRset-Gap Fill消息。將MsgSeqNu過高的接收消息排隊暫存。
|
13
|
在實踐間隔後未收到消息
|
Y
|
Y
|
沒有非混亂消息在HeartBeatInt+響應時間內被接收,發送TestRequest消息。
|
14
|
等待/處理TestRequest消息響應
|
Y
|
Y
|
處理接收消息。當接收到非混亂消息後,復位心跳間隔時間。
|
15
|
接收Logout消息
|
Y
|
Y
|
從對端接收到發起註銷/連接斷開的Logout消息。如果MsgSeqNum過高,發送RsendRequest。如果發送,等待一定週期,以完成ResendRequest的響應處理。注意,依據Logout的原因,對端可能不能執行該請求。 發送Logout消息作爲響應並等待一定時間讓對端斷開網絡連接。注意,對端可能發送ResendRequest消息,如果Logout響應消息的MsgSeqNum過高並重新發起Logout操作。
|
16
|
發起Logout處理
|
Y
|
Y
|
識別優雅斷開連接的條件和原因(如:日終,多個未響應的TestRequest消息發送後,MsgSeqNum過高等)。發送Logout效益給對端。等待一個時間週期以接收Logout響應。在這期間,如有可能,處理新接收的消息和/或ResendRequest。注意,一些註銷/終止條件(如數據庫/消息存儲失敗),可能要求緊接在初始滬Logout消息發送後立即止網絡連接。斷開該會話的網絡連接並關閉該會配置。
|
17
|
活動/正常會話
|
Y
|
Y
|
網絡連接建立後,Logon消息成果交換完成,接收和發送的MsgSeqNum都是所期望的順序,並且Heartbeat 或其他消息在(HeartBeatInt +響應週期)內被接收。
|
18
|
等待Logon確認
|
Y
|
N
|
會話發起者等待會話接收者發送Logon確認消息。
|
Session Initiator(e.g. buyside)Action 會話發起者(如,買方)行爲
|
Session Acceptor(e.g. sellside)Action會話接收者(如,賣方)行爲
|
Session Initiator(e.g.buyside)State會話發起者(如,買方)狀態
|
Session Acceptor(e.g. sellside)State會話接收者(如,賣方)狀態
|
開始
|
|
未連接-當日未連接
未連接-當日連接
|
等待連接
|
連接
|
|
發起連接
(可能)檢測到網絡連接中斷
|
等待連接
|
|
接受連接
|
建立網絡連接
|
建立網絡連接
|
發起登陸
|
|
發送發起登陸消息Logout
|
建立網絡連接
|
|
收到發起登陸消息Logout
|
發送發起登陸消息Logout
|
收到發起登陸消息Logout
|
|
發送發起登陸消息響應
|
發送發起登陸消息Logout
|
發起Logon的響應
(可能)發起 Logout處理
(可能)接收到的MsgSeqNum過高
|
|
(可能)發送ResendRequest
|
|
發起Logon響應
(可能)接收到的MsgSeqNum過高
|
接收發起登陸消息的響應
|
|
(可能)活動/正常的會話
(可能)發起 Logout處理(如,MsgSeqNum過高)
|
發起Logon的響應
|
(可能)發送RsendRequest
|
|
(可能)活動/正常的會話
(可能)接收的MsgSeqNum過高
|
(可能)活動/正常的會話
(可能)處理ResendRequest
|
|
|
活動/正常的會話
|
活動/正常的會話
|
Logout Initiator: Action
Logout發起者行爲ie
|
Logout Acceptor Action
Logout接收者行爲
|
Logout Initiator State
Logout發起者狀態
|
Logout Acceptor State
Logout接收者狀態
|
開始
|
|
1. 活動/正常的會話
2. 沒有在時間間隔內收到消息
3. 等待/處理響應TestRequest
|
|
|
|
|
|
Ref ID參考號
|
Pre-
Condi-
tion
前置
條件
|
Test
case
測試
用例
|
Mandaory
/Optional
強制
/可選
|
Condition
/Stimulus
狀態
/激發
|
Expected Beheavior期望行爲
|
1B
|
|
連接併發送Logon消息
|
Mandatory
強制
|
a 建立網絡連接
|
同對端成功創建TCP socket連接
|
|
|
|
|
b 發送Logon消息
|
發送Logon消息
|
|
|
|
|
c 收到有效Logon響應消息
|
如果MsgSeqNum過高,則發送Resend Request消息
|
|
|
|
|
d 收到無效Logon消息
|
1. 在測試輸出上產生一個錯誤狀態。
2. (可選)發送Reject駁回消息,其RefMsgSeqNum 參照Logon消息的MsgSeqNum的值,在Text 域填寫錯誤狀態。
3. 發送Logout消息,在其Text域填寫錯誤狀態。
4. 斷開連接。
|
|
|
|
|
e 收到任何非Logon消息
|
1. 記錄日誌:第一個消息不是Logon。
2. 同上
3. 同上
4. 同上
|
Ref ID參考號
|
Pre-
Condi-
tion
前置
條件
|
Test
case
測試
用例
|
Mandaory
/Optional
強制
/可選
|
Condition
/Stimulus
狀態
/激發
|
Expected Beheavior期望行爲
|
1S
|
|
收到Logon消息
|
Mandatory
強制
|
a收到有效Logon響應消息
|
1. 用Logon響應消息進行響應
2. 如果MsgSeqNum過高,則發送Resend
Request消息
|
|
|
|
|
b 收到帶有重複特性的Logon消息(如,當存在連接時的同樣的IP,Port,SenderCompID,TargetCompID,等)
|
1. 產生,並測試輸出一個錯誤狀態。
2. 不發送任何消息,斷開連接。(注意,發送Reject消息,或Logout消息將消耗MsgSeqNum)
|
|
|
|
|
c 收到Logon消息,帶有未認證/未配置特性(如,同系統配置比較,無效SendCompID,無效TargetCompID,無效源IP等)
|
1. 產生,並測試輸出一個錯誤狀態。
2. 不發送任何消息,斷開連接。(注意,發送Reject消息,或Logout消息將消耗MsgSeqNum)
|
|
|
|
|
d 收到無效Logon消息
|
1. 在測試輸出上產生一個錯誤狀態。
2. (可選)發送Reject駁回消息,其RefMsgSeqNum參照Logon消息的MsgSeqNum的值,在Text 域填寫錯誤狀態。
3. 發送Logout消息,在其Text域填寫錯誤狀態。
4. 斷開連接。
|
|
|
收到任何非Logon消息
|
Mandatory
強制
|
第一個消息不時一個Logon消息
|
1. 記錄日誌:第一個消息不是Logon。
2. 斷開連接
|
Ref ID參考號
|
Pre-
Condi-
tion
前置
條件
|
Test
case
測試
用例
|
Mandaory
/Optional
強制
/可選
|
Condition
/Stimulus
狀態
/激發
|
Expected Beheavior期望行爲
|
2
|
|
收到消息標準頭
|
Mandatory
強制
|
A收到期望的MsgSeqNum
|
接受該消息的MsgSeqNum
|
|
|
|
|
b 收到比期望值大的MsgSeqNum
|
用Resend Request消息作爲響應
|
|
|
|
|
c 收到比期望值小的MsgSeqNum且PossDupFlag不爲‘Y’
列外:SeqReset-Reset
|
1. 推薦FIX引擎嘗試發送一個Logout,並帶有Text的值爲“MsgSeqNum
too low,expecting X but receiced Y”
2. (可選)等待Logout消息的響應(注意:可能會出現的錯誤的MsgSeqNum)或者等待2秒無論什麼先到達
3. 斷開連接
4. 產生、輸出錯誤報告
|
|
|
|
|
d 收到混亂消息
|
1. 當做混亂消息並忽略消息(不增加輸入MsgSeqNum),繼續接收消息。
2. 產生並輸出“警告”測試信息。
3. 發送Logout消息,在其Text域填寫錯誤狀態。
4. 斷開連接。
|
|
|
|
|
e PossDupFlag值爲‘Y’;OrigSendingTime值小於或等於SendingTime且MsgSeqNum比期望值小。
注意:OrigSendingTime應遭遇SendingTime除非該消息在同一秒內重傳。
|
1. 檢查是否該MsgSeqNum值消息已經被接收。
2. 如果已經收到,忽略該消息,否則接收並處理該消息。
|
|
|
|
|
f PossDupFlag值爲‘Y’,OrigSendingTime比SendingTime大,且MsgSeqNum等於期望值
注意:OrigSendingTime應遭遇SendingTime除非該消息在同一秒內重傳。
|
1. 發送Reject駁回消息,參照不準確的發送時間(>=FIX4.2:SessionRejectReason
= “SendingTime 準確性問題”)
2. 增加接收MsgSeqNum值
3. 可選:
a) 發送Logtout消息,參照不準確的SendingTime值
b) (可選)等待Logout響應(注意有可能有不準確的SendingTime)或者等待2秒無論什麼消息先到達。
c) 斷開連接。
產生、輸出一個“錯誤”測試信息。
|
|
|
|
|
g PossDupFlag值爲‘Y’,OrigSendingTime沒有指定
注意:在響應Resen Request消息時,始終將OrigSendingTime設置爲消息最開始發送的時間,不是當前SendingTime時間,並且PossDuFlag=‘Y’
|
1. 發送Reject駁回消息,參照不準確的發送時間(>=FIX4.2:SessionRejectReason
= “tag丟失”)
2. 增加接收MsgSeqNum值
|
|
|
|
|
h 收到在測試Profile中指定的期望的BeginString值,並且匹配發送消息的BeginString值
|
接受該消息的BeginString
|
|
|
|
|
i收到不是在測試Profile中指定的期望的BeginString值,並且匹配發送消息的BeginString值
|
1. 發送Logout消息參照錯誤的BeginString值。
2. (可選)等待Logout響應消息(注意可能有錯誤的BeginString)或者等待2秒無論什麼先到達
3. 斷開連接。
4. 產生、輸出“錯誤“測試信息。
|
|
|
|
|
j收到在測試Profile中指定的期望的SenderCompID和TargetCompID值
|
接受該消息的SenderCompID和TargetCompID
|
|
|
|
|
k收到不是在測試Profile中指定的期望的SenderCompID和TargetCompID值
|
1. 發送Reject駁回消息,參照無效的SenderCompID和TargetCompID。(>=FIX4.2:SessionRejectReason
= “CompID錯誤”)
2. 增加接收MsgSeqNum值。
3. 參照錯誤的SenderCompID或TargetCompID值發送Logout消息。
4. (可選)等待Logout響應消息(注意可能有錯誤的SenderCompID或TargetCompID值)或者等待2秒無論什麼先到達
5. 斷開連接
6. 產生、輸出“錯誤”測試信息。
|
|
|
|
|
l 收到正確的BodyLength值
|
接受該消息的BodyLength
|
|
|
|
|
m收到正確的BodyLength值
|
1. 當做混亂消息並忽略(不增加接收MsgSeqNum值),繼續接收消息。
2. 產生、輸出“警告”測試信息。
|
|
|
|
|
N SendingTime值使用UTC格式並在一個基於原子時間的合理範圍內(如,2秒)
|
接受該消息的SendingTime
|
|
|
|
|
O收到的SendingTime值即不使用UTC格式也不是在一個基於原子時間的合理範圍內(如,2秒)
|
1. 發送Reject駁回消息,參照無效的SendingTim。(>=FIX4.2:SessionRejectReason
= “SendingTime精確性問題”)
2. 增加接收MsgSeqNum值
3. 參照不精確的SendingTime發送Logout消息。
4. (可選)等待Logout響應消息(注意可能有不精確的SendingTime)或者等待2秒無論什麼先到達
5. 斷開連接
6. 產生、輸出“錯誤”測試消息。
|
|
|
|
|
P 收到有效MsgType值(在規範中定義或用戶自定義文檔中定義)
|
接受該消息的MsgType
|
|
|
|
|
收到無效MsgType值(沒有在規範中定義或用戶自定義文檔中定義)
|
1. 發送Reject駁回消息,參照無效的MsgType。(>=FIX4.2:SessionRejectReason
= “無效的MsgType”)
2. 增加接收MsgSeqNum值
3. 產生、輸出“警告”測試消息
|
|
|
|
|
R收到有效MsgType值(在規範中定義或用戶自定義文檔中定義)但不被測試Profile支持,或沒再其中註冊。
|
1. if < FIX 4.2 參照有效的但不被支持的MsgType發送Reject駁回消息。
2. if >=FIX4.2
a) 發送Business Message
Reject駁回消息,參照有效但不被支持的MsgType。(>=FIX4.2:BusinessRejectReason
= “不支持的MsgType”
3. 增加接收MsgSeqNum值
4. 產生、輸出“警告”測試消息
|
|
|
|
|
S 收到的BeginStirng,BodyLength,和MsgType是消息的前三個域
|
接受該消息
|
|
|
|
|
t 收到的BeginStirng,BodyLength,和MsgType是消息的前三個域
|
1. 當做混亂消息並忽略(不增加接收MsgSeqNum值),繼續接收消息。
2. 產生、輸出“警告”測試消息
|
3
|
|
接收標準消息尾
|
強制
|
a 有效CheckSum
|
1. 接受消息
|
|
|
|
|
B 無效CheckSum
|
1. 當做混亂消息並忽略(不增加接收MsgSeqNum值),繼續接收消息。
2. 產生、輸出“警告”測試消息
|
|
|
|
|
C 混亂消息
|
1. 當做混亂消息並忽略(不增加接收MsgSeqNum值),繼續接收消息。
2. 產生、輸出“警告”測試消息
|
|
|
|
|
D CheckSum爲消息的最後一個域,長度爲3,並由分界符<SOH>分隔
|
接受該消息
|
|
|
|
|
E CheckSum不是消息的最後一個域,長度不爲3,或不是由分界符<SOH>分隔
|
1. 當做混亂消息並忽略(不增加接收MsgSeqNum值),繼續接收消息。
2. 產生、輸出“警告”測試消息
|
4
|
|
發送Heartbeat消息
|
強制
|
A 當前心跳時間間隔內無數據發送(HeartBearInt域)
|
發送Heartbeat消息
|
|
|
|
|
B接收到一個Test Request消息
|
發送Heartbeat消息,附帶Test Request消息的TestReqID
|
5
|
|
接收Heartbeat消息
|
強制
|
有效的Heartbeat消息
|
接受Heartbeat消息。
|
6
|
|
發送Test Request
|
強制
|
當前心跳時間間隔+某個時間週期(20%的HeartBeatInt值)內無數據接收
|
1. 發送Test Request消息
2. 跟蹤確認一個使用TestReqID的Heartbeat被接收(可以不是下一個消息)。
|
7
|
|
接收Reject駁回消息
|
強制
|
有效的Reject消息
|
1. 增加接收MsgSeqNum值
2. 繼續接收消息
|
8
|
|
接收Resend Request消息
|
強制
|
有效的Resend Request消息
|
使用應用層消息,和按照“消息恢復”規則在請求範圍內使用SequenceReset-Gap Fill消息進行響應
|
9
|
|
同步序列號
|
可選
|
應用程序故障
|
發送Sequence Reset-Reset消息或手動復位
|
10
|
|
接收Sequence Reset(Gap Fill)
|
強制
|
A 收到Sequence Reset(Gap Fill)消息,NewSeqNo
> MsgSeqNum 且MsgSeqNum > 期望序列號
|
發送Resend Request,在最後一個期望MsgSeqNum到接收到的MsgSeqNum範圍內填衝消息間隙。
|
|
|
|
|
B收到Sequence Reset(Gap Fill)消息,NewSeqNo
> MsgSeqNum 且MsgSeqNum = 期望序列號
|
設置下一個期望序列號爲NewSeqNo
|
|
|
|
|
C收到Sequence Reset(Gap Fill)消息,NewSeqNo
> MsgSeqNum 且MsgSeqNum < 期望序列號且
PossDupFlag = “Y”
|
忽略消息
|
|
|
|
|
D收到Sequence Reset(Gap Fill)消息,NewSeqNo
> MsgSeqNum 且MsgSeqNum < 期望序列號且
沒有PossDupFlag = “Y”
|
1. 如果可能,在斷開FIX會話前,發送帶有Text域爲“MsgSeqNum
too low, expecting X received Y,”的Logout消息
2. (可選)等待Logout響應(注意可能有不精確的MsgSeqNum)或者等待2秒無論什麼先到達)
3. 斷開連接
4. 產生、輸出“錯誤”測試信息。
|
|
|
|
|
E收到Sequence Reset(Gap Fill)消息,NewSeqNo
<= MsgSeqNum 且MsgSeqNum = 期望序列號
|
發送Reject(會話層)駁回消息,攜帶信息“attempt to lower sequnce number, invalid value NewSeqNum=<x>”
|
11
|
|
接收Sequence Reset(Reset)
|
強制
|
A 收到Sequence Reset(Gap Fill)消息,NewSeqNo> 期望序列號
|
1. 接受該Sequence Reset消息,忽略其MsgSeqNum
2. 將期期望序列號設置爲NewSeqNo
|
|
|
|
|
B收到Sequence Reset(Gap Fill)消息,NewSeqNo= 期望序列號
|
1. 接受該Sequence Reset消息,忽略其MsgSeqNum
2. 產生、輸出“警告”測試信息。
|
|
|
|
|
C收到Sequence Reset(Gap Fill)消息,NewSeqNo< 期望序列號
|
1. 接受該Sequence Reset消息,忽略其MsgSeqNum
2. 發送Reject會話層駁回消息,參照無效的MsgType。(>=FIX4.2:SessionRejectReason
= “此tag值錯誤(超界)”)
3. 不增加接收MsgSeqNum值
4. 產生、輸出“錯誤”測試消息。
5. 不能減小序列號。
|
12
|
|
發起註銷過程
|
強制
|
發起Logout
|
1. 發送Logout消息
2. 10秒內等待Logtout響應(注意,可能由於出現的通信問題不能收到)。如果沒有收到,產生輸出“警告”測試消息
3. 斷開連接。
|
13
|
|
接收Logtout消息
|
強制
|
A 收到有效的Logout消息作爲請求註銷處理過程的響應
|
斷開連接,不發送消息。
|
|
|
|
|
B 接收到有效的非請求的Logout消息
|
1. 發送Logout響應消息。
2. 10秒內等待對端斷開連接。如果超過等待時間,斷開連接,產生輸出“錯誤”測試消息
|
14
|
|
接收應用消息或管理消息
|
強制
|
A收到的域識別符(tag值)未在規範文檔中定義
例外:未在規範文檔中定義,但在測試Profile中作爲用戶定義的tag
|
1. 發送Reject會話層駁回消息,參照無效的tag。(>=FIX4.2:SessionRejectReason
= “無效的tag”)
2. 增加接收MsgSeqNum。
3. 產生、輸出“錯誤”測試消息
|
|
|
|
|
B 接收消息中必選Tag丟失
|
1. 發送Reject會話層駁回消息,參照丟失的必選tag。(>=FIX4.2:SessionRejectReason
= “必選tag丟失”)
2. 增加接收MsgSeqNum。
3. 產生、輸出“錯誤”測試消息
|
|
|
|
|
C 接收消息tag在規範文檔中定義,但不是爲該消息類型定義的
|
1. 發送Reject會話層駁回消息,參照丟不是爲該消息類型定義的tag。(>=FIX4.2:SessionRejectReason
= “該消息未定義此Tag”)
2. 增加接收MsgSeqNum。
3. 產生、輸出“錯誤”測試消息
|
|
|
|
|
D 接收消息tag在規範文檔中定義,但爲空值(如55=<SOH>)
|
1. 發送Reject會話層駁回消息,參照已定義但值爲空的tag。(>=FIX4.2:SessionRejectReason
= “指定的Tag值爲空”)
2. 增加接收MsgSeqNum。
3. 產生、輸出“錯誤”測試消息
|
|
|
|
|
E 接受消息特定tag值取值、取值範圍錯誤,或不是有效的枚舉值。
例外:在測試Profile中作爲用戶自定義的未在規範文檔中定義的枚舉值
|
1. 發送Reject會話層駁回消息,參照取值錯誤的tag。(>=FIX4.2:SessionRejectReason
= “Tag值錯誤(超界)”)
2. 增加接收MsgSeqNum。
3. 產生、輸出“錯誤”測試消息
|
|
|
|
|
F接受消息特定tag值格式(語法)錯誤
|
1. 發送Reject會話層駁回消息,參照取值格式錯誤的tag。(>=FIX4.2:SessionRejectReason
= “值格式錯誤”)
2. 增加接收MsgSeqNum。
3. 產生、輸出“錯誤”測試消息
|
|
|
|
|
G 消息結構不是和ader+body+trailer
|
1. 發送Reject會話層駁回消息,參照不正確地消息結構。(>=FIX4.2:SessionRejectReason
= “指定的Tag順序錯誤”)
2. 增加接收MsgSeqNum。
3. 產生、輸出“錯誤”測試消息
|
|
|
|
|
H 消息中一個tag不是重複組的組成部分,但被多次指定
|
1. 發送Reject會話層駁回消息,參照重複的tag。(>=FIX4.2:SessionRejectReason
= “Tag重複出現”)
2. 增加接收MsgSeqNum。
3. 產生、輸出“錯誤”測試消息
|
|
|
|
|
I 消息中重複組count域值錯誤
|
1. 發送Reject會話層駁回消息,參照錯誤的count域。(>=FIX4.2:SessionRejectReason
= “重複組無效的NumInGroup計數”)
2. 增加接收MsgSeqNum。
3. 產生、輸出“錯誤”測試消息
|
|
|
|
|
J 重複組域順序未匹配規範
|
1. 發送Reject會話層駁回消息,參照重複組錯誤的域順序。(>=FIX4.2:SessionRejectReason
= “重複組域順序錯誤”)
2. 增加接收MsgSeqNum。
3. 產生、輸出“錯誤”測試消息
|
|
|
|
|
K 域的tag標識中含有多個<SOH>(非域數據)
|
1. 發送Reject會話層駁回消息,參照域的含有多個<SOH>的tag標識。(>=FIX4.2:SessionRejectReason
= “非域數據包含分界符號(SOH 字符)”)
2. 增加接收MsgSeqNum。
3. 產生、輸出“錯誤”測試消息
|
|
|
|
|
L 當應用曾處理或系統無效收到消息
|
1. if <FIX 4.2
a) 發送Reject會話層駁回消息,參考應用處理無效。
2. if >=FIX 4.2
a) 發送Business Message
Reject消息,參考域參考應用處理無效。(>=FIX4.2:BusinessRejectReason = “應用程序無效”)
4. 增加接收MsgSeqNum。
5. 產生、輸出“警告”測試消息
|
|
|
|
|
M 消息中常規必選域丟失
|
1. if <FIX 4.2
b) 發送Reject會話層駁回消息,參考丟失的常規必選域。
2. if >=FIX 4.2
a) 發送Business Message
Reject消息,參考丟失的常規必選域。(>=FIX4.2:BusinessRejectReason = “常規必選域丟失”)
3. 增加接收MsgSeqNum。
4. 產生、輸出“錯誤”測試消息
|
|
|
|
|
N 在明文中出現的Tag數與密文中出現的相同,但Tag值不同
|
1. 發送Reject會話層駁回消息,參照明文和密文中具有相tag數,但值不同的域。(>=FIX4.2:SessionRejectReason
= “解密問題/錯誤”)
2. 增加接收MsgSeqNum。
3. 產生、輸出“錯誤”測試消息
|
15
|
|
發送應用或管理消息以測試正常和異常的行爲/響應
|
|
發送多個消息同類消息,其頭部和數據體域順序不同,以驗證消息接受(排除有順序限制的)
|
消息被接受並且其後續消息的MsgSeqNum被接受。
|
16
|
|
排隊待發送消息
|
強制
|
A 當處於連接斷開時待發消息排隊
|
排隊待發送消息。注意,有2種方法:
1. 排隊消息,不考慮MsgSeqNum
a) 存儲消息數據。
2. 使用下一個MsgSeqNum值,排隊每一個消息
a) 採用消耗下一個MsgSeqNum值的方式,存儲消息數據。
注意:SendingTime(Tag#52):必須包是消息發送的時間,而不是消息進入排隊的時間。
|
|
|
|
|
B 帶有排隊消息的重連。
|
1. 完成登陸過程(連接,交換Logon消息)
2. 如可能,完成MsgSeqNum恢復過程。
3. 推薦短暫延遲或使用TestRequest/Heartbeat確認MsgSeqNum恢復完成。
4. 注意,這裏有2種有效的排隊方法:
a) 排隊消息,不考慮MsgSeqNum
i. 使用新MsgSeqNum發送排隊消息(大於Logon消息的MsgSeqNum)。
b) 使用下一個MsgSeqNum值,排隊每一個消息
i. (注意,)Logon消息的MsgSeqNum大於排隊消息的MsgSeqNum。
ii. 對端將發起ResendRequest請求這個範圍內丟失的消息
iii. 重發每個排隊消息,將PossDupFlag設置爲‘Y’
注意:SendingTime(Tag#52):必須包是消息發送的時間,而不是消息進入排隊的時間。
|
17
|
|
加密支持
|
可選
|
A 接收Logon消息,帶有有效的北支持的EncryptMethod
|
1. 接受該消息
2. 執行適當的解密或加密方法。
3. 使用同一個EncryptMethod方法響應Logon消息。
|
|
|
|
|
B 收到Logon消息,帶有無效的或不支持的EncryptMethod
|
1. 發送Reject會話層駁回消息,參照無效的或不支持EncryptMethod。(>=FIX4.2:SessionRejectReason
= “解密問題”)
2. 增加接收MsgSeqNum值。
3. 發送Logout消息,參照無效的或不支持EncryptMethod
4. (可選)等待Logout響應(注意可能有解密問題)或者等待2秒無論什麼先到達)
5. 斷開連接
6. 產生、輸出“錯誤”測試消息。
|
|
|
|
|
C 收到消息,帶有SignatureLength和Signature值
|
接受該消息
|
|
|
|
|
D 收到消息,帶有無效的SigntureLength值
|
1. 發送Reject會話層駁回消息,參照無效的SignatureLength值。(>=FIX4.2:SessionRejectReason
= “簽名問題”)
2. 增加接收MsgSeqNum值。
3. 產生、輸出“錯誤”測試消息。
|
|
|
|
|
E收到消息,帶有無效的Signture值
|
1. 發送Reject會話層駁回消息,參照無效的Signature值。(>=FIX4.2:SessionRejectReason
= “簽名問題”)
2. 增加接收MsgSeqNum值。
3. 產生、輸出“錯誤”測試消息。
或者,考慮解密錯誤或順序錯誤的消息,忽略消息(不增加接收MsgSeqNum值)並繼續接收消息。
|
|
|
|
|
F 收到消息,有有效的SecureDataLen和SecureData值,且能被解密爲有效的,能接戲的明文
|
接收消息。
|
|
|
|
|
G 接收消息SecureDataLen值無效
|
1. 當做解密錯誤或消息順序錯,忽略消息(不增加接收MsgSeqNum值)並繼續接收消息。
2. 產生、輸出“警告”測試消息。
|
|
|
|
|
H 接收消息帶有不能被解密爲有效、能被解析的明文
|
1. 發送Reject會話層駁回消息,參照無效的SecureData值。(>=FIX4.2:SessionRejectReason
= “解密問題”)
2. 增加接收MsgSeqNum值。
3. 產生、輸出“錯誤”測試消息。
|
|
|
|
|
I 接收消息中一個或多個域本應按規範不能被加密的,未出現在非加密部分
|
1. 發送Reject會話層駁回消息,參照不能加密的丟失域的Tag值。(>=FIX4.2:SessionRejectReason
= “解密問題”)
2. 增加接收MsgSeqNum值。
3. 產生、輸出“錯誤”測試消息。
|
|
|
|
|
J 接收消息有按照指定的Encryp他Method有錯誤的“left
over”字符處理(如,當密文前的明文長度部位8的倍數時)
|
1. 發送Reject會話層駁回消息,參照錯誤的“left
over”字符處理。(>=FIX4.2:SessionRejectReason = “解密問題”)
2. 增加接收MsgSeqNum值。
3. 產生、輸出“錯誤”測試消息
|
18
|
|
支持第三方尋址
|
可選
|
A 接收消帶有OnBehalfOfCompI和DeliverToCompID值,同測試Profile中指正確用法相符
|
接收消息
|
|
|
|
|
B接收消帶有OnBehalfOfCompI和DeliverToCompID值,同測試Profile中指正確用法不相符
|
1. 發送Reject會話層駁回消息,參照無效的OnBehalfOfCompI和DeliverToCompID。(>=FIX4.2:SessionRejectReason
= “CompID問題”)
2. 增加接收MsgSeqNum值。
3. 產生、輸出“錯誤”測試消息
|
19
|
|
測試PossResend處理
|
強制
|
A 接收消息帶有PossResend=‘Y’且應用層消息ID檢查顯示其已經在本次會話中出現過
|
1. 忽略該消息
2. 產生、輸出“警告”測試消息。
|
|
|
|
|
B接收消息帶有PossResend=‘Y’且應用層消息ID檢查顯示其已經在本次會話中沒有出現過
|
接受並正常處理該消息。
|
20
|
|
同時Resend 請求測試
|
強制
|
當已經發送和等待一個Resend Request消息的所有響應後,接收到一個Resend Request消息
|
1. 執行請求被請求消息的重傳。
2. 發送Resend Request消息請求丟失消息重發。
|
|
|
|
|
|
|