但是後來我想想,站在軟體角度,如果像是teamviewer那種架構,或是類似line聊天軟體,根本不需要知道對方的IP/Gateway,一樣可以連線溝通啊。而且我們設備上層還是軟體架構,如果用軟體架構實現,再去透過抓包解析後設定到硬體,這樣路就通了。所以想說利用Python來快速實做一下聊天軟體,OK的話再回去C++/C# AP那邊添加功能。
簡單來說,就是有一個中央負責處理轉發的Server,以及連線到Server的許多的Client。Client之間,只需要利用ID來識別,就可以傳送資料。就像是聊天軟體一樣簡單達到需求。
「架構規劃與定義」
流程大概就是幾個client端連線之後,可以看到彼此,進而傳遞訊息,因此我畫出底下的圖代表。Server由上而下有時間的順序。根據上面的圖,可以看出主要溝通訊息可以分成四類:connect(紅),friends(藍),message(綠),disconnect(黃)。原先想用類似C++ structure方式組包來送訊息,但因為這單純聊天比較簡單,只有幾種型態,我就以純文字方式定義就好。訊息中夾帶多組參數,會以"/"隔開。不用反斜線,因為會有跳脫字元問題。
- 。connect:Client發連線訊息給Server,夾帶name訊息。Server會建立新連線。 connect/name:Client1
- 。friends:Server接收到connect/disconnect訊息時,會整理朋友列表清單,傳送給所有Client。 friends/client1/client2
- 。message:Client1傳送聊天訊息給Server,Server根據來源目的,轉發給Client2。 message/to:Client2/from:Client1/hello
- 。disconnect:Client發斷線訊息給Server,夾帶name訊息。Server會斷開Client連線。 disconnect/name:Client1
「實做部分」
要做到這樣效果,是利用Socket。Python在使用socket上是非常非常方便的。Socket Server/Client的寫法網路上已經一堆了,如何連線,傳送接受,斷線就不用敘述了,底下就說明幾個方向。Server部分:
Server需要接收很多連線,故我寫一個簡單class去記錄每一個connection的handle, portnum, 以及名稱,然後把每個connection class去append到一個connection list中,形成一個client列表。我定義Server是被動部分,有連線或是命令進來才有相對應反應,本身不會自己主動發什麼訊息的。因此接收部分,共會接收到三種命令:- 連線命令:
- 格式 connect/name:client1
- 處理:分析出client名稱之後,保存至connection list
- 反應
- Server對此client回傳message訊息當做回應,內容為"Hello clientname"
- Server根據connection list清單建立friends訊息,回傳給所有connection
- 斷線命令:
- 格式 disconnect/name:client1
- 處理:分析出client名稱之後,從connection list中移除,並關閉連線
- 反應:Server根據重整後的connection list清單,建立friends訊息,回傳給所有connection
- 訊息命令:
- 格式 message/to:client2/from:client1/hello
- 處理:分析出給那個client名稱,並在connection list清單找到目的client
- 反應
- Server將message訊息轉發給目的client
- Server將message訊息轉發給來源client
Client部分:
Client部分除了主動向Server傳送訊息之外,還會接收來自於Server的回應。傳送部分有三個命令:- 連線命令:
- 格式 connect/name:client1
- 處理:將自己的名稱(ID),組成命令之後,發送至Server
- 斷線命令:
- 格式 disconnect/name:client1
- 處理:用戶按下close之後,將自己的名稱(ID),組成命令之後,發送至Server
- 訊息命令:
- 格式 message/to:client2/from:client1/hello
- 處理:根據用戶選擇的目的client,自己的ID以及要傳送的訊息,組成命令之後,發送至Server
- 朋友清單命令:
- 格式 friends/client1/client2/......
- 處理:分析出每個client名稱
- 反應:添加至朋友清單
- 斷線確認命令:
- 格式 disconnect/name:client1
- 處理:確保Server回應這個client斷線,表示Server已經把client從清單中移除並斷線
- 反應:關閉視窗
- 訊息命令:
- 格式 message/to:client2/from:client1/hello
- 處理:分析出給來自那個client名稱,以及訊息內容。
- 反應:顯示在螢幕上
「結果呈現部分」
一個Server,以及可以支援多個Client。有多個連線之後,Client可以跟線上其他Client丟訊息,被丟訊息的Client也會看到是誰來的。編碼用utf-8,就可以支援中文:
當我將其中一個連線關閉時,另一個client端也會同步更新清單,可以看見斷線的client被移除了。
「腳本下載」
。Server。Client
「後記」
。Server沒有考量到複雜度,所以當client需求多的時候,效率應該會很差。以展示來說應該夠了。。Server沒有太多功能,重新連線,踢掉Client等功能沒做。界面上只有記錄而已,有單調
。Client因為簡單展示,沒使用帳號密碼登入。
。結構可以再定義更多,比方說分組。
。雖然腳本開始有判斷Python2/3,但實際上只在Python 2.7跑過,版本3應該會有問題
。還很多沒考量的......
0 意見:
張貼留言