2013-09-26 92 views
1

我正在创建一个C#套接字用于UDP接收和发送功能与接收的异步回调函数。简单,对!消除所有皱纹需要花费一段时间,但它可以起作用......呃,只要你把港口弄死了!我需要允许其他应用程序使用相同的端口号。没问题,对!有该选项,SetSocketOption(...)为ReuseAddress ...当我将ReuseAddress设置为true时,为什么NO回调从BeginReceive? UDP

udpClient.SetSocketOption(SocketOptionLevel.Udp, SocketOptionName.ReuseAddress, true); 

为什么,当我设置ReuseAddress为true,则回调函数不会被打了?

using System; 
using System.Net; 
using System.Net.Sockets; 
using System.Text; 
using System.Threading; 
using System.Windows.Forms; 
using CSharpUtilityLibrary.Utilities; 

namespace CSharpNIU.Sockets 
{ 
     public class PacketEventArgs : EventArgs { 
     public byte[] Bytes { get; set; } 
     public PacketEventArgs(byte[] bytes) 
     { 
     Bytes = bytes; 
     } 
    } 

    public delegate void PacketEventHandler(object sender, PacketEventArgs e); 

    // State object for reading client data asynchronously 
    public class StateObject 
    { 
     // Client socket. 
     public Socket workSocket = null; 

     // Size of receive buffer. 
     public const int BufferSize = 1553; 

     // Receive buffer. 
     public byte[] buffer = new byte[BufferSize]; 
    } 

    public class UDPSocket 
    { 
     // Thread signal. 
     public ManualResetEvent allDone = new ManualResetEvent(false); 

     public String ApplicationName { get; set; } 
     public Form ParentForm { get; set; } 
     public Network ApplicationNetwork { get; set; } 
     private ConfigGeneric Config { get; set; } 
     private Socket udpClient = null; 

     public UDPSocket(ConfigGeneric config, String applicationName) 
     { 
     Config = config; 

     ApplicationDetails appDetails = config.GetApplicationByName(applicationName); 
     if (appDetails == null) 
      return; 

     ApplicationNetwork = config.GetNetworkByName(appDetails._network); 
     if (ApplicationNetwork == null) return; 
     } 

     public void StartListening() 
     { 
     // Data buffer for incoming data. 
     byte[] bytes = new Byte[1024]; 

     IPAddress ipAddress = IPAddress.Parse(ApplicationNetwork._networkAddress); 
     IPEndPoint localEndPoint = new IPEndPoint(ipAddress, ApplicationNetwork._receivePort); 

     // Create a UDP Socket 
     udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 

     // Bind the socket to the local endpoint 
     try 
     { 
      // Set the event to nonsignaled state. 
      allDone.Reset(); 

      // Start an asynchronous socket to listen for connections. 
      allDone.Set(); 
      StateObject stateObject = new StateObject(); 
      stateObject.workSocket = udpClient; 
//------> The line Below causes the begin receive to not call ReadCallback <-------// 
      udpClient.SetSocketOption(SocketOptionLevel.Udp, SocketOptionName.ReuseAddress, true); 
//------> The line Above causes the begin receive to not call ReadCallback <-------// 
      udpClient.Bind(localEndPoint); 

      udpClient.BeginReceive(stateObject.buffer, 0, StateObject.BufferSize, SocketFlags.None, new AsyncCallback(ReadCallback), stateObject); 

      // Wait until a connection is made before continuing. 
      allDone.WaitOne(); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e.ToString()); 
     } 
     } 

     public void ReadCallback(IAsyncResult ar) 
     { 
     String content = String.Empty; 

     // Retrieve the state object and the handler socket from the asynchronous state object. 
     StateObject state = (StateObject)ar.AsyncState; 
     Socket handler = state.workSocket; 

     // Read data from the client socket. 
     int bytesRead = handler.EndReceive(ar); 

     if (bytesRead > 0) 
     { 
      PacketEventArgs packetEventArgs = new PacketEventArgs(state.buffer); 
      OnRecevedPacket(packetEventArgs); 

      // There might be more data, so store the data received so far. 
      udpClient.BeginReceive(state.buffer, 0, StateObject.BufferSize, SocketFlags.None, new AsyncCallback(ReadCallback), state); 
     } 
     } 

     // Event Handlers 
     public event PacketEventHandler ReceiveCallback; 

     protected virtual void OnRecevedPacket(PacketEventArgs e) 
     { 
     if (ReceiveCallback != null) 
      ReceiveCallback(this, e); 
     } 

     public void Send(byte[] bytes) 
     { 
     // Begin sending the data to the remote device. 
     IPAddress ipAddress = IPAddress.Parse(ApplicationNetwork._broadcastAddress); 
     IPEndPoint endPoint = new IPEndPoint(ipAddress, ApplicationNetwork._receivePort); 

     udpClient.SendTo(bytes, endPoint); 
     } 
    } 
} 
+0

*更新* 我只注意到SetSocketOption抛出“无效的参数提供”,从而防止BeginReceive从获取调用的异常。我有更多的调查。 – Dainon

+0

我还没有找到什么说什么使该行有一个无效的论点。我注意到有人在使用UdpClient并使用SocketOptionLevel.Socket设置套接字选项。这摆脱了异常,但仍然没有对ReadCallback函数的回调。 – Dainon

回答

相关问题