views:

369

answers:

1

I have the following UDP broadcast listener running as a static component in a seperate thread on an ASP.NET web application. Why I would do this is really, unimportant, but the reason why this wont work when deployed baffles me. I do have several console applications sending UDP broadcasts, and I've coded tested and confirmed this thread and its code working when running under Visual Studio on the VS2005 development web server, but the moment that I compile the code and deploy it to another machine and run it under IIS - it stops working. Furthermore, it doesnt ERROR, it just doesn't work.

The log4net logging also seems to only work in the Init() method, but not the thread (which is weird). But I have added some File.AppendAllText's to the thread and it DOES seem to be executing, but as far as I can tell, it stops on the line byte[] received = mUdpClient.Receive(ref mGroupEP);

I've made sure the port is open and tested in a console app (which works), I've checked permissions, even made the default identity use the Local System user account, but still nothing. I've checked the firewall, checked the event log - nothing. No errors, just not working.

I wondered if it might be somehting to do with IIS shutting down System.Net requests as a security meassure, but I can't find anything that might support that hypothesis.

  public class UDPBroadcastListener {

    #region Members

    private ILogger mLogger = NullLogger.Instance;

    private readonly int mPort;
    private UdpClient mUdpClient;
    private IPEndPoint mGroupEP;

    public event EventHandler<GenericEventArgs<byte[]>> Received;

    private Thread mThread;

    #endregion

    public UDPBroadcastListener(int port) {
      mPort = port;
    }

    public void Init() {
      try {
        Logger.WarnFormat("Setting up the UDP packet listener on port {0}", mPort);
        mGroupEP = new IPEndPoint(IPAddress.Any, mPort);
        mUdpClient = new UdpClient();
        mUdpClient.EnableBroadcast = true;
        mUdpClient.Client.SetSocketOption(SocketOptionLevel.Socket,
                                          SocketOptionName.ReuseAddress,
                                          true);
        mUdpClient.Client.Bind(mGroupEP);
        Logger.InfoFormat("Successfully bound the UDP packet listener to the the port.");

        mThread = new Thread(UpdateThread);
        mThread.IsBackground = true;
        Logger.Info("Starting the background listener thread.");
        mThread.Start();
        Logger.InfoFormat("Background listener thread started ok.");
      } catch (Exception e) {
        Logger.Error(e.Message, e);
      }
    }

    public void Close() {
      if (mThread != null) {
        mThread.Abort();
      }

      if (mUdpClient != null) {
        mUdpClient.Close();
        mUdpClient = null;
      }
    }

    public Thread Thread {
      get { return mThread; }
    }

    private void UpdateThread() {
      Logger.Info("Listener thread started.");
      while (true) {
        try {
          Logger.Info("Waiting for broadcast");

          byte[] received = mUdpClient.Receive(ref mGroupEP);

          Logger.InfoFormat("Received {0} bytes", received.Length);
          OnReceived(received);
        } catch (Exception ex) {
          Logger.Error(ex.Message, ex);
        }
      }
    }

    protected void OnReceived(byte[] pData) {
      EventHandler<GenericEventArgs<byte[]>> handler = Received;
      if (handler != null) Received(this, new GenericEventArgs<byte[]>(pData));
    }

    public virtual ILogger Logger {
      get { return mLogger; }
      set { mLogger = value; }
    }

    #region Dispose

    private bool mDisposed = false;

    public void Dispose() {
      if (mDisposed) return;

      mDisposed = true;

      Close();
    }

    ~UDPBroadcastListener() {
      Dispose();
    }

    #endregion

  }
}

I am now getting extremely desperate. Please help. :(

+1  A: 

You could try investigating with TCPView (It shows UDP as well) to see if anything shows up on the production server. Check out "Troubleshooting Windows Firewall settings", although this is for XP and I doubt your production server is XP, but it may be helpful anyway. See the netstat example.

David Glass
Thanks for this suggestion, using it I was able to see that it WAS a firewall issue after all - I had opened the ports, but they were set to TCP, not UDP. Sigh, hours of debugging/testing wasted.
Ash