[英]How to implement a network protocol?
這是一個通用的問題。 我不是在尋找最好的答案,我希望你能表達你最喜歡的做法。
我想用Java實現一個網絡協議(但這是一個相當普遍的問題,我在C ++中面臨同樣的問題),這不是第一次,正如我之前所做的那樣。 但我認為我錯過了實施它的好方法。 實際上通常都是關於在主機之間交換文本消息和一些字節緩沖區,存儲狀態並等到下一條消息到來。 問題是我通常最終得到一堆開關,並且或多或少復雜的if語句對不同的狀態/消息作出反應。 整件事情通常變得復雜而難以保持。 更不用說有時出現的東西有一些“盲點”,我的意思是協議的狀態沒有被覆蓋並且以不可預測的方式表現。 我試着寫下一些狀態機類,負責以或多或少的智能方式檢查每個動作的開始和結束狀態。 這使編程協議變得非常復雜,因為我必須編寫行和代碼行來覆蓋每種可能的情況。 我喜歡的是一個好的模式,或者用於編寫復雜協議的最佳實踐,易於維護和擴展,並且非常易讀。
你有什么建議?
閱讀狀態設計模式,了解如何避免大量的switch語句。
“有時會出現一些”盲點“,我的意思是協議的狀態尚未涵蓋......”
國家可以幫助避免差距。 它不能保證良好的設計,你仍然必須這樣做。
“......因為我必須編寫代碼行和代碼行以涵蓋所有可能的情況。”
這不應被視為負擔或問題:您必須編寫代碼行以涵蓋所有可能的情況。
State可以提供幫助,因為您可以利用繼承。 它不能保證良好的設計,你仍然必須這樣做。
設計協議通常都與您正在使用的應用程序空間有關。 例如,http就是處理網頁,圖形和帖子,而FTP則是關於傳輸文件。
簡而言之,首先,您應該確定您所處的應用程序空間,然后定義需要采取的操作。 最后,在你開始設計你的實際協議之前,你應該認真地,認真地尋找另一個做你想做的事情的協議棧,並避免實現協議棧altoether。 只有在您確定預先構建的其他內容絕對不適合您之后,才能開始構建自己的協議棧。
有限狀態機就是你想要的
因此,您可以定義一大堆狀態,您可以將其作為接收方或發送方(空閑,連接_phase1,連接_用於預期的數據包,...)
然后定義所有可能的事件(packet1到達,net關閉,......)
最后你有一個表,說'當狀態為x且事件n發生了func y並轉換到狀態q'時 - 表示每個狀態和事件(很多都是null或dups)
編輯 - 如何制作FSM(粗略草圖)
struct FSMNode
{
int m_nextState;
void (m_func*);
}
FSMNode states[NUMSTATES][NUMEVENTS]=
{ // state 0
{3, bang}, // event 0
{2,wiz},
{1, fertang}
}
{
{1, noop}, // event 0
{1, noop},
{3, ole}
}
.......
FSMNode node = states[mystate][event];
node.m_func(context);
mystate = node.m_nextState;
我確信這充滿了無效的語法 - 但我希望你得到漂移
在C ++中,您可以使用Boost :: Spirit庫輕松地解析協議消息。 唯一的“難點”是定義消息協議的語法。 看看Gnutella源代碼,看看他們是如何解決這個問題的。 這里http://www9.limewire.com/developer/gnutella_protocol_0.4.pdf是Gnutella協議規范
為什么不使用XML作為協議? 您可以在XML節點內封裝和分類所有數據
不能自己給你一個例子,但是如何看待其他(有能力的)人們如何做呢?
像這個? http://anonsvn.jboss.org/repos/netty/trunk/src/main/java/org/jboss/netty/handler/codec/http/
PS就此而言,我實際上建議使用netty作為您的網絡框架並在其上構建您的協議。 它應該很容易,你可能會擺脫一堆頭痛......
如果您使用的是Java,請考慮查看Apache MINA ,它的文檔和示例應該以正確的方式激勵您。
右鍵單擊系統托盤中的網絡連接圖標。 單擊“疑難解答”。 問題排查工具可能會找到並解決問題,在這種情況下,您可以快速開始使用您的業務。 如果故障排除程序無法解決Winsocks問題,則可能會出現以下錯誤:“此計算機上缺少一個或多個網絡協議”
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.