2009-07-29 145 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第一。这样网络地形的影响就会减小,当一切按您期望的方式工作时,您可以将其移动到广播地址。