2015-06-16 34 views
1

我爲我的在線遊戲製作了一個服務器(python,twisted)。從TCP開始,然後在UDP中添加了不斷的更新(看到一個很大的速度提升)。但現在,我需要將每個UDP套接字客戶端與每個TCP客戶端連接起來。UDP和TCP對於一個客戶端總是使用相同的IP?

我這樣做是通過讓每個客戶端首先連接到TCP服務器並獲取唯一的ID。然後客戶端將此ID發送到UDP服務器,並將其連接。然後我有一個主要的TCP客戶端列表(由唯一ID排序)。

我的目標是能夠通過TCP和UDP將消息發送到同一個客戶端。
將UDP和TCP套接字鏈接到同一客戶端的最佳方法是什麼?

我可以只取一個新的TCP客戶端的IP地址,並通過UDP將數據發送到該IP?還是有必要爲客戶端連接兩次,一次用於TCP和一次用於UDP(通過發送'連接'消息)?

最後,如果有TCP/UDP知識的人可以告訴我(我是新手!),當通過UDP與TCP(來自同一臺機器)連接時,同一客戶端是否具有相同的IP地址?(我需要知道這一點,以保護我的服務器,但我不想意外阻止一些公平的用戶)

回答

1

回答你的最後一個問題:沒有。因爲:

  1. 如果客戶端位於NAT之後,並且網關(使用NAT)具有多個IP,則您可以將每個連接看作是來自不同IP的連接。
  2. 另一個問題是,當同一個NAT後面的幾個不同的客戶端將與您的服務器連接時,您將擁有多對TCP-UDP客戶端。並且不可能加入正確的配對。

你的方法似乎是解決這個問題的好方法。

+0

謝謝,作爲一個更新:我的方法工作正常,我已經發布了一個成功的iOS實時多人遊戲使用它:)它使用UDP爲非可靠的消息,TCP爲可靠的東西。遊戲鏈接:https://itunes.apple.com/ca/app/blewp!-eat-or-be-eaten-mmo/id996122625?mt=8 –

1

1-我可以只取一個新的TCP客戶端的IP地址,並通過UDP將數據發送到該IP?沒有在一般情況下,但...

2-是否有必要爲客戶端連接兩次,一次爲TCP和一次爲UDP?否,確切地說

3-當UDP連接到TCP(來自同一臺計算機)連接時,同一個客戶端是否具有相同的IP地址?是的,除特殊情況外

您確實需要一些關於TCP,UDP和IP協議的基本知識,以進一步理解OSI模型。

基礎(但你應該閱讀維基百科的文章有一個更深入的瞭解):

  • TCP和UDP 2個協議在IP
  • IP是可路由的協議:它可以通過路由器
  • TCP是連接協議:它可以通過網關或代理(防火牆和NAT)
  • UDP在未連接的協議:它不能穿過網關
  • 單個機器可公頃一個接口可能有多個IP地址
  • 在一般情況下,客戶端機器只有一個網絡接口和一個IP地址 - 無論如何,當連接到服務器時,您可以要求客戶端向TCP和UDP提供相同的地址
  • 網絡地址轉換是指本地網絡和始終顯示其自己的IP地址並跟蹤TCP連接將數據包發送回正確的客戶端

事實上,最se問題在於客戶端和服務器之間是否存在網關。儘管客戶端和服務器是兩臺可直接訪問鍵盤的(虛擬)機器,但沒有問題,但公司網絡通常由用作NAT的防火牆保護,而且許多國內的ADSL路由器還包括防火牆和NAT。在這種情況下,忘記UDP。可以指示國內路由器將所有UDP流量傳遞給單個本地IP,但這不一定是件容易的事。此外,這意味着如果您的用戶在家中有多臺機器,他將被允許一次只使用一臺機器,並且必須重新配置他的路由器才能切換到另一臺機器!

+0

這就是爲什麼NA​​T也包含UDP路由表的原因。只要客戶端首先開始講話,UDP就可以穿越NAT和防火牆。他目前的方法將起作用。 – crazyhatfish

1

首先,當您使用TCP或UDP發送數據時,您必須給出端口。

如果您的客戶端連接到TCP,並且您的服務器使用UDP發送響應後,數據包將被客戶端拒絕。

爲什麼?因爲您必須註冊一個端口進行連接,並且您無法確定端口在客戶端上是否正確打開。

所以當你在TCP中開始一個連接時,客戶端打開一個端口發送數據並接收響應。你必須對UDP做相同的處理。當客戶端開始與服務器的所有通信時,您可以確定所有必需的端口都已打開。

不要忘記在連接打開的端口上發送數據。

我可以只取一個新的TCP客戶端的IP地址,並通過UDP將數據發送到該IP?或者客戶端需要連接兩次,一次用於TCP,一次用於UDP(通過發送'連接'消息)?

爲什麼你不想創建2個連接? 例如,您必須使用UDP進行移動。因爲如果你創建一個FPS,你可以每50ms發送一次該玩家的位置,所以使用UDP非常重要。

這不僅僅是一個更好的連接問題。如果您希望在客戶端和服務器之間建立良好的連接,則需要使用異步連接並使用STREAM。但是如果你使用流,你的TCP套接字不會指示套接字的結束,但你有更好的傳輸。所以你必須寫一些東西來顯示數據包的結尾(例如<EOF>)。 但你有這個問題。您收到的每個套接字都必須分析數據並拆分<EOF>。它可能需要很多處理器。

對於UDP,數據包總是有結束信號。但是你需要實施安全檢查。