2010年6月10日 星期四

網路遊戲數據傳輸和防火牆穿越

一般來說,client和server之間的數據交換,分為幾個優先級,大部分情況下是下面3種: 1. 不可以丟失,但是不要求速度。 2. 不可以丟失,但是要求速度,確並不是非常嚴格。 3. 可以丟失,但是要求速度 對於1來說,最直接的例子就是聊天信息,動態的地圖信息。這些數據不是time-critical的,所以應該使用TCP連接。在大多數情況下,有專門的voice/chat server和map server,client到每個server有個TCP連接。一個client有多少個連接根據需要決定。同時有2-3個連接並沒有多大開銷。當然,如果開銷很大,就是程序設計的問題了。其實你想想開BT的時候同時有4,50個連接,你用其他程序的速度並沒有慢多少。 對於2來說,比較顯著的例子是戰鬥信息,動作序列。比如一個人玩遊戲,用鼠標點了下地圖上的一個坐標,那麼人物向這個坐標前進。這個信息從server轉發到其他的client,當然越快越好,如果client沒收到,就要重發,否則client就看不到這個動作。如果你玩過wow的盜賊,就會發現在網絡卡的時候,經常先偷襲,按下鍵盤以後要等一會才看到攻擊動作,就是這個原理。當然這里數據需要經過server的處理,每次打包多個client的動作,和順序,然後發送。需要復雜的server端邏輯處理。這種應該使用UDP,同時對所有的UDP包編號(用來防止2次處理),使用slide window類似的協議進行重傳。 對於3來說,就是位置信息。位置信息可以丟失,但是由於這種信息更新的最頻繁,所以即使丟失其中一個,也可以根據dead reckoning 算法進行位置預測和修正。 dead reckoning算法有很多變種,適合多類情況。比如你見過wow裡,如果一個人掉線,但是一直往前不停的跑,那多半就是算法進行的預測。偶爾你會發現網絡卡的時候,剛剛走到一個地方就退回到原來的位置,就是因為你的動作數據包(2裡的)沒發送出去,導致update world position的時候,算法進行位置修正的結果。這類數據應該使用UDP. 需要說明的是 UDP和TCP無明顯分界。 TCP相比UDP,有3個主要缺點,1是slow start, 2是throughput jitter, 3是insistence on reliability(相對的,不時絕對缺點). 在數據傳送量比較小,網絡狀況比較穩定的情況下,使用TCP和UDP無大分別。 對於防火牆穿透,如果你是做client的,不需要關心這個問題,因為你往Server發數據,建立連接,都不會受到防火牆的影響。不過server端對於放火牆可以有幾種實現方式: 1. 最差的方式是client發送SYN包給服務器,在防火牆或網關上建立NAT地址,然後Server之需要取得這個NAT地址,把所有的數據包都封裝成SYN-ACK包,發給client就行拉。這樣做比較省事。但是無法穿透 stateful firewall 2. 是比較好的方式。不過需要先建立TCP連接,然後對server發送正常的UDP包。大部分的NAT網關會為UDP專門建立個NAT地址,那麼通過這個地址,server就可以發UDP包了。但是並不是所有的firewall都會為UDP建立單獨的NAT地址。 3. 是最好的方式,由於防火牆不會阻止內部網發起的TCP連接,所以TCP進行數據傳輸沒有任何問題。對於Server/Client來說,只要使用Raw Socket模擬TCP協議,但是這個模擬的TCP協議使用UDP的本質,沒有slide window, 沒有congestion control, 沒有flow control等等,這種實現最麻煩,但是幾乎能處理所有的防火牆。 4. 其實沒有4,不過實在想提下這種最強技術. 就是所有的Server到Client的數據包都可以是ICMP echo reply message. 由於種種原因,firewall不太可能禁止ICMP echo,所以這類消息也是很容易傳送到client,但是。 。 。 。 。 。 。 。 Client如果有IDS system,很容易把你的sever歸類到入侵掃描的範圍。所以不用最好。 如果你們不是採用第3種方式,並且你只寫client,那麼防火牆跟你就沒有什麼關係。都是server的事。 引述於: http://wlvfox.javaeye.com/blog/494573

沒有留言:

張貼留言