2012-12-01 40 views
3

我正在製作一個連接到桌面應用程序的Win RT應用程序,他們開始使用UDP和TCP進行通信。DatagramSocket無法接收來自UdpClient的數據

我已經成功實現了TCP通信,我可以從Win RT發送到桌面並從桌面發送到Win RT。在Win RT上使用StreamSocket,在桌面上使用TcpListener。

我也使它從Win RT發送Udp數據到桌面沒有任何問題。但我無法接收從桌面發送到Win RT的數據。我使用下面的代碼,我沒有看到任何問題,但必須有一些。

var g = new DatagramSocket(); 
    g.MessageReceived += g_MessageReceived; 
    g.BindEndpointAsync(new HostName("127.0.0.1"), "6700"); 
    . 
    . 
    . 
    void g_MessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args) 
    { // <- break point here. 

    } 

該斷點永遠不會停止代碼,這意味着它永遠不會收到消息。 我只能想到IBuffer,因爲在我的StreamSocket上,我應該通過reader.GetBuffers()獲取字節,而不是reader.GetBytes()。但是,這是我需要考慮在Win RT而不是桌面上的事情。因爲在Tcp上我只是發送字節,並且我在Win RT中獲得緩衝區,所以DatagramSocket也應該發生這種情況。

  • 讀卡器= DataReader的

謝謝你們。

+0

本文可能有所幫助。 http://msdn.microsoft.com/en-us/library/windows/apps/Hh780593.aspx –

回答

5

我不熟悉新的DatagramSocket類,但通常綁定到127.0.0.1意味着您將只接收發送到回送適配器的消息。由於您的數據包來自另一臺主機,因此它們應該在網卡上接收,而不是回送適配器。

編輯:通過觀察爲您使用DatagramSocket的API文檔,你可以只使用BindServiceNameAsync()方法,而不是BindEndpointAsync()以綁定到所有適配器指定的端口,這是相同的行爲作爲我下面的System.Net.Sockets API示例。所以,在你的榜樣,你必須:

g.BindServiceNameAsync("6700"); 

當然,你還需要確保在桌面主機上的防火牆設置允許它偵聽指定端口上的傳入UDP數據包。

試試下面的代碼:

using System.Net; 
    using System.Net.Sockets; 

    public class UdpState 
    { 
     public UdpClient client; 
     public IPEndPoint ep; 
    } 

    ... 

    private void btnStartListener_Click(object sender, EventArgs e) 
    { 
     UdpState state = new UdpState(); 
     //This specifies that the UdpClient should listen on EVERY adapter 
     //on the specified port, not just on one adapter. 
     state.ep = new IPEndPoint(IPAddress.Any, 31337); 
     //This will call bind() using the above IP endpoint information. 
     state.client = new UdpClient(state.ep); 
     //This starts waiting for an incoming datagram and returns immediately. 
     state.client.BeginReceive(new AsyncCallback(bytesReceived), state); 
    } 

    private void bytesReceived(IAsyncResult async) 
    { 
     UdpState state = async.AsyncState as UdpState; 
     if (state != null) 
     { 
      IPEndPoint ep = state.ep; 
      string msg = ASCIIEncoding.ASCII.GetString(state.client.EndReceive(async, ref ep)); 
      //either close the client or call BeginReceive to wait for next datagram here. 
     } 
    } 

注意,在上面的代碼,很顯然你應該使用什麼編碼您跨與發送的字符串。當我編寫測試應用程序時,我用ASCII發送了字符串。如果您使用Unicode發送,則只需使用UnicodeEncoding.Unicode而不是ASCIIEncoding.ASCII

如果這些都不起作用,您可能需要突破像Wireshark這樣的數據包捕獲實用程序,以確保來自RT主機的UDP數據包事實上正在到達桌面主機。

+0

您有沒有機會嘗試將'BindEndpointAsync'更改爲'BindServiceNameAsync'?我沒有Windows 8開發工具,所以我不能自己嘗試,但是從MSDN文檔看,您的代碼應該適用於該更改。此外,如果您需要能夠在Win 8之前的Windows版本上運行您的代碼,我提供的代碼應該可以工作。我已經測試過它。 – reirab

+0

我還沒有嘗試過你的代碼,但我確實嘗試了根據MSDN的BindServiceNameAsync等於IPAddress.Any上的綁定並沒有發生任何事情。我想這應該是在編碼,最大字節大小或像這樣的一些屬性的差異。 – Peyman

+0

和127.0.0.1應該不是問題,因爲我在具有相同IP的仿真器上測試。但是,爲了確保我做到了這一點,它沒有工作:( – Peyman