2013-08-27 6 views
0

Я пытался отправить udp-пакет из эмулятора wp7 на свой сервер (java-сервер на том же ПК) и получить ответ. Я использовал код класса SocketClient из MSDN: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh202864(v=vs.105).aspx.Не могу получить Udp в телефоне Windows

Он работает совершенно нормально, когда:

  1. Каждый раз, когда я создаю экземпляр класса Socketclient и посыла вызова() и получить() метод.
  2. после отправки пакета с использованием send() Я могу получить несколько пакетов, вызывающих receive() несколько.

Но проблема это-

  1. Я создаю экземпляр класса Socketclient и посыла вызова() и получить() метод затем снова посыла вызова() и получить() (из того же объекта Socketclient класс). В этой ситуации он может отправить пакет во второй раз без ответа (дает ответ «тайм-аут операции»).

Если я создаю новый объект класса Socketclient для отправки и получения снова, он работает, но я должен использовать один сокет все время в моем проекте. Как я могу это решить? Вот код-

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Net.Sockets; 
using System.Threading; 
using System.Net; 
namespace UdpClient 
{ 
    class SocketClient 
    { 
     // Cached Socket object that will be used by each call for the lifetime of this class 
     Socket _socket = null; 
     // Signaling object used to notify when an asynchronous operation is completed 
     static ManualResetEvent _clientDone = new ManualResetEvent(false); 
     // Define a timeout in milliseconds for each asynchronous call. If a response is not received within this 
     // timeout period, the call is aborted. 
     const int TIMEOUT_MILLISECONDS = 5000; 
     // The maximum size of the data buffer to use with the asynchronous socket methods 
     const int MAX_BUFFER_SIZE = 2048; 
     /// <summary> 
     /// SocketClient Constructor 
     /// </summary> 
     public SocketClient() 
     { 
      // The following creates a socket with the following properties: 
      // AddressFamily.InterNetwork - the socket will use the IP version 4 addressing scheme to resolve an address 
      // SocketType.Dgram - a socket that supports datagram (message) packets 
      // PrototcolType.Udp - the User Datagram Protocol (UDP) 
      _socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 
     } 
     /// <summary> 
     /// Send the given data to the server using the established connection 
     /// </summary> 
     /// <param name="serverName">The name of the server</param> 
     /// <param name="portNumber">The number of the port over which to send the data</param> 
     /// <param name="data">The data to send to the server</param> 
     /// <returns>The result of the Send request</returns> 
     public string Send(string serverName, int portNumber, string data) 
     { 
      string response = "Operation Timeout"; 
      // We are re-using the _socket object that was initialized in the Connect method 
      if (_socket != null) 
      { 
       // Create SocketAsyncEventArgs context object 
       SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs(); 
       // Set properties on context object 
       socketEventArg.RemoteEndPoint = new DnsEndPoint(serverName, portNumber); 
       // Inline event handler for the Completed event. 
       // Note: This event handler was implemented inline in order to make this method self-contained. 
       socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e) 
       { 
        response = e.SocketError.ToString(); 
        // Unblock the UI thread 
        _clientDone.Set(); 
       }); 
       // Add the data to be sent into the buffer 
       byte[] payload = Encoding.UTF8.GetBytes(data); 
       socketEventArg.SetBuffer(payload, 0, payload.Length); 
       // Sets the state of the event to nonsignaled, causing threads to block 
       _clientDone.Reset(); 
       // Make an asynchronous Send request over the socket 
       _socket.SendToAsync(socketEventArg); 
       // Block the UI thread for a maximum of TIMEOUT_MILLISECONDS milliseconds. 
       // If no response comes back within this time then proceed 
       _clientDone.WaitOne(TIMEOUT_MILLISECONDS); 
      } 
      else 
      { 
       response = "Socket is not initialized"; 
      } 
      return response; 
     } 




     /// <summary> 
     /// Receive data from the server 
     /// </summary> 
     /// <param name="portNumber">The port on which to receive data</param> 
     /// <returns>The data received from the server</returns> 
     public string Receive(int portNumber) 
     { 
      string response = "Operation Timeout"; 
      // We are receiving over an established socket connection 
      if (_socket != null) 
      { 
       // Create SocketAsyncEventArgs context object 
       SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs(); 
       socketEventArg.RemoteEndPoint = new IPEndPoint(IPAddress.Any, portNumber); 
       // Setup the buffer to receive the data 
       socketEventArg.SetBuffer(new Byte[MAX_BUFFER_SIZE], 0, MAX_BUFFER_SIZE); 
       // Inline event handler for the Completed event. 
       // Note: This even handler was implemented inline in order to make this method self-contained. 
       socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e) 
       { 
        if (e.SocketError == SocketError.Success) 
        { 
         // Retrieve the data from the buffer 
         response = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred); 
         response = response.Trim('\0'); 
        } 
        else 
        { 
         response = e.SocketError.ToString(); 
        } 
        _clientDone.Set(); 
       }); 
       // Sets the state of the event to nonsignaled, causing threads to block 
       _clientDone.Reset(); 
       // Make an asynchronous Receive request over the socket 
       _socket.ReceiveFromAsync(socketEventArg); 
       // Block the UI thread for a maximum of TIMEOUT_MILLISECONDS milliseconds. 
       // If no response comes back within this time then proceed 
       _clientDone.WaitOne(TIMEOUT_MILLISECONDS); 
      } 
      else 
      { 
       response = "Socket is not initialized"; 
      } 
      return response; 
     } 

     /// <summary> 
     /// Closes the Socket connection and releases all associated resources 
     /// </summary> 
     public void Close() 
     { 
      if (_socket != null) 
      { 
       _socket.Close(); 
      } 
     } 

    } 
} 

ответ

0

Проблема была в функции приема. Пакетные данные были асинхронно назначены на строковый ответ, но он возвращал ответ переменной из текущего потока до завершения операции receiveAsync.