2009-07-29 131 views
3

我對下面的代碼有問題。它所做的是使用UDP廣播發送當前日期/時間並監聽此消息。我目前使用的這段代碼是本地的,我在同一臺計算機上使用同一個應用程序中的發送和接收。我沒有在2臺電腦之間嘗試。爲什麼我收到兩次通過UDP廣播發送的數據?

public class Agent 
{ 
    public static int Port = 33333; 
    public delegate void OnMessageHandler(string message); 

    Socket socketSend; 
    Socket socketReceive; 

    bool receiving = false; 
    Thread receiveThread; 

    public event OnMessageHandler OnMessage; 

    public Agent() 
    { 
     socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 
     socketSend.EnableBroadcast = true; 

     socketSend.Connect(new IPEndPoint(IPAddress.Broadcast, Port)); 

     socketReceive = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 
     socketReceive.EnableBroadcast = true; 

     socketReceive.Bind(new IPEndPoint(IPAddress.Any, Port)); 
    } 

    public void Start() 
    { 
     Console.WriteLine("Agent started!"); 

     receiving = true; 
     receiveThread = new Thread(new ThreadStart(Receive)); 
     receiveThread.IsBackground = true; 
     receiveThread.Start(); 
    } 

    public void Stop() 
    { 
     receiving = false; 

     socketSend.Close(); 
     socketReceive.Close(); 

     receiveThread.Join(); 

     Console.WriteLine("Agent ended."); 
    } 

    public void Send(string message) 
    { 
     Console.WriteLine("Sending : {0}", message); 
     byte[] bytes = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, Encoding.Unicode.GetBytes(message)); 
     socketSend.Send(bytes); 
     Console.WriteLine("Message sent."); 
    } 

    protected void Receive() 
    { 
     Console.WriteLine("Thread started!"); 
     while (receiving) 
     { 
      try 
      { 
       if (socketReceive.Available > 0) 
       { 
        byte[] bytes = new byte[socketReceive.Available]; 

        Console.WriteLine("Waiting for receive..."); 

        int bytesReceived = socketReceive.Receive(bytes, SocketFlags.None); 
        Console.WriteLine("Bytes received : {0}", bytesReceived); 

        string message = Encoding.UTF8.GetString(bytes); 
        Console.WriteLine("Received message : {0}", message); 
        OnMessage(message); 
       } 
       else 
       { 
        Console.Write("."); 
        Thread.Sleep(200); 
       } 
      } 
      catch (SocketException ex) 
      { 
       if (ex.SocketErrorCode == SocketError.Interrupted) 
       { 
        break; 
       } 
       else 
       { 
        throw; 
       } 
      } 
     } 
     Console.WriteLine("Thread ended."); 
    } 
} 

我的問題是,它發送該數據一次(當我點擊一個按鈕),但它接收兩次預期的量。例如,正常日期/時間長度爲19個字節,但第一次可用時間> 0,其值爲38.在接收呼叫之後只抓取19個字節,並且循環繼續接下來的19個字節。這意味着我收到我的信息兩次,我當然只需要一次。輸出的

例子:

Agent started! 
Thread started! 
..........Sending : 29/07/2009 12:05:04 
Message sent. 
Waiting for receive... 
Bytes received : 19 
Received message : 29/07/2009 12:05:04 
Waiting for receive... 
Bytes received : 19 
Received message : 29/07/2009 12:05:04 
......Thread ended. 
Agent ended. 
+0

爲什麼睡覺?任何體面的套接字庫都將包含阻塞讀取方法。 (我根本不知道C#,但我假設有一個socketReceive.read()或類似的方法。) – 2009-07-29 10:17:32

回答

4
socketReceive.Bind(new IPEndPoint(IPAddress.Any, Port)); 

通過綁定到所有IP地址,您將獲得本地環回並通過網絡。

+0

非常感謝,我獲得了第一個接口的本地IP地址,並且它工作並將其用於socketReceive。 – speps 2009-07-29 10:45:09

0

我建議你試試這件指定的目標IP第一。這樣網絡地形的影響就會減小,當一切按您期望的方式工作時,您可以將其移動到廣播地址。