2011-08-13 60 views
0

過去幾天我問了幾個類似的問題,並得到了一些非常大的幫助。我現在明白我的問題好多了,但我似乎遇到了困難。我編寫了一個同時使用TCP和UDP連接的客戶端服務器應用程序。 TCP連接可以在LAN和WAN上正常工作,但UDP連接在WAN上失敗。根據我之前詢問的問題,我意識到我的服務器需要回復收到通信的EndPoint客戶端。我把所有東西都設置成這樣工作。我會在問題後張貼代碼。我現在的問題是,當我從客戶端連接使用EndPoint並且客戶端首先建立連接時,我仍然無法建立UDP連接。它似乎在一個網絡上工作,但對我嘗試過的所有其他網絡失敗了。任何幫助搞清楚這一點表示讚賞。這是代碼。廣域網上的UDP傳輸

接收服務器上的UDP消息

private void receiveUDP() 
    { 
     System.Net.IPEndPoint test = new System.Net.IPEndPoint(System.Net.IPAddress.Any,UDP_PORT); 
     System.Net.EndPoint serverIP = (System.Net.EndPoint)test; 
     trans.Bind(serverIP); 
     System.Net.IPEndPoint ipep = new System.Net.IPEndPoint(System.Net.IPAddress.Any, 0); 
     System.Net.EndPoint Remote = (System.Net.EndPoint)ipep; 

     while (true) 
     { 

      byte[] content = new byte[1024]; 

      int recv = trans.ReceiveFrom(content,ref Remote); 

      int portNum = ((System.Net.IPEndPoint)Remote).Port; 
      string message = Encoding.ASCII.GetString(content); 
      string[] data = message.Split((char)124); 
      //UpdateStatus(data[0] + data[1]); 

      UserConnection sender = (UserConnection)clients[data[0]]; 
      if (sender.PortNumber != portNum) 
       sender.PortNumber = portNum; 
      if (sender.RemoteEnd != Remote) 
      { 
       sender.RemoteEnd = Remote;//Stores the EndPoint from the client connection 
      } 
      if (data.Length > 2) 
      { 
       OnLineRecieved(sender, data[1] + "|" + data[2]); 
      } 
      else 
      { 
       OnLineRecieved(sender, data[1]); 
      } 
     } 
    } 

客戶端偵聽這裏

private void receiveUDP() 
    { 
     System.Net.IPEndPoint test = new System.Net.IPEndPoint(System.Net.IPAddress.Any,UDP_PORT_NUMBER); 
     System.Net.EndPoint serverIP = (System.Net.EndPoint)test; 
     server.Bind(serverIP); 
     server.Ttl = 50; 

     EndPoint RemoteServ = (EndPoint)servIP; 
     while (true) 
     { 
      byte[] content = new byte[1024]; 
      int data = server.ReceiveFrom(content, ref RemoteServ); 

      string message = Encoding.ASCII.GetString(content); 
      result = message; 

      ProcessCommands(message); 

     } 
    } 

編輯:服務器的發送功能

public void SendData(string data) 
    { 
     if (RemoteEnd != null)//RemoteEnd is refreshed every time the client sends a UDP message 
//Each Clients RemoteEnd is stored in a collection of Client objects in a server hashtable 
     { 
      //ipep = new IPEndPoint(ipAdd, PortNumber); 
      byte[] dataArr = Encoding.ASCII.GetBytes(data); 

      trans.SendTo(dataArr, dataArr.Length, SocketFlags.None, RemoteEnd); 
     } 
    } 
+2

您使用路由器嗎?如果是這樣,您的服務器必須以某種方式(可能通過添加到您的路由器的DMZ)對局域網以外的客戶端「可見」。 – Kiril

+0

@Lirik客戶端實際上能夠與服務器通信,但服務器無法回覆任何這些通信。 – Stephen

+1

我沒有看到你的服務器的發送代碼...你能發表一些代碼來描述你的服務器在發送數據嗎? – Kiril

回答

1

可能有很多事情是錯誤的。請記住,UDP不提供傳輸步調,重傳或確認。所以,如果你需要他們,必須提供他們。如果您先讓客戶端發送,然後等待每個查詢的響應,那麼您的第一個丟失的數據包將會終止連接。

你也忘了描述這個問題。你說你沒有建立聯繫,但這意味着什麼?服務器是否收到客戶端的第一個數據包?客戶端是否收到服務器的第一個答覆?

+0

對不起,我沒有足夠清楚地解釋這個問題。客戶端首先發送數據。服務器接收數據就好了,因爲服務器有必要的端口轉發。但是,客戶端沒有收到任何回覆。我沒有讓客戶端收聽每封郵件的回覆。相反,它隨時都會收聽任何回覆。客戶端根本沒有收到任何返回消息。 – Stephen

+1

服務器是否使用它收到的相同套接字發送?你可以使用'tcpdump'來捕獲接收UDP數據包的服務器併發送一個UDP數據包並將它們粘貼到這裏?(比較數據包,一個的源IP /端口應該是另一個的目的地,反之亦然,反之亦然)。 –

+0

是的,我會這樣做,並儘快發佈結果。 – Stephen

1

您必須確定這是編程問題還是網絡配置問題。

我會做的是在服務器機器上運行客戶端應用程序,並在客戶機上運行服務器應用程序(並切換它們連接的主機)。

如果服務器應用程序不再接收來自客戶端應用程序的UDP消息,那麼您有網絡配置問題。

如果服務器應用程序仍然可以從客戶端應用程序接收消息,那麼您有一個編程問題。