2010年2月17日 星期三

聊天室練習 - III. 網路設定、接收與傳送

Panda3D的網路設定參考這裡

NetworkLib.py 中,函數NetworkSetupServer與NetworkSetupClient分別設定連線為server或是client端。連線成功後,將處理網路封包讀取與檢查連線狀態的task加至系統中,server端還會多加入"聽"client連結的task。
NetworkConnectionTarget 這個list保存連線的對象。網路封包讀取時,用以標明是哪個對象送來的封包(NetworkLib.py,第229行)。與網路封包傳送時,用以表示送 給哪個對象的封包(NetworkLib.py,第175行,第189行)。檢查連線狀態與移除連線時也用於表示對象(NetworkLib.py,第 248行,第256,257行)。server端的NetworkConnectionTarget依序存放連進來的client。client端的 NetworkConnectionTarget僅保存server為其唯一的連線對象。

網路封包傳送的運作,只要 呼叫NetworkDataObjSend或NetworkDataObjSendAll函數。在這個練習中,NetworkDataObjSend是設 計給client,以傳送給它唯一的對象,NetworkDataObjSendAll是設計給server,以傳送封包給它所有的client對象。設計的原因在稍後討論Server - Client 間的傳輸協定時在說明。

雖然panda3D支援將整數,浮點數,字串等形態物件以個別方式填入封包,參考這裡, 如整數就依byte需求分成getInt8,getInt16,getInt32,getInt64等處理函數。針對不同需求使用對應函數應該會得到較小的封包,但讀取時需要依序呼叫對應的處理函數,相當於寫一個parser來還原封包內容,當傳輸內容或順序更改時,對應的還原封包函數也得變動。且這些支 援的型態並不包含list或dictionary等python內建型態。使用此方式包裝資料有取得較小封包的優點,但代價是較複雜的還原封包內容的方式。

這個練習中並沒有使用上述方式,而是以python提供的cPickle.dumps函數,將python物件打包成字串,再將此字串以zlib.compress壓縮後傳送。還原封包的流程正好相反,將讀取的封包內容字串以zlib.decompress解壓 縮,再用cPickle.loads還原成物件。這樣雖然會產生較大的封包,但在處理資料填入封包與還原的方式較簡單,並且可以傳送任何python物件,於新一版panda3D 1.7中,甚至可以傳送panda3d內的自訂物件如point3等。

網 路封包讀取的操作為:每個frame執行tskReaderPolling這個task,檢查是否有封包進入。當封包進入時,以前一段的描述方式從封包擷取資料,最後呼叫封包處理函數NetworkDataObjGet。NetworkDataObjGet為一空函數,預留給真正做資料處理的函數覆載 (ChatRoomMain.py,第40行)

下圖為資料由接收端,經過網路至傳送端,傳送端解開資料並處理的示意流程。




----

  1. 操作方式
  2. 程式架構
  3. 網路設定、接收與傳送
  4. Server - Client 間的傳輸協定
  5. 傳輸命令格式
  6. GUI
  7. 中文輸入與顯示
  8. 事件驅動

沒有留言: