home
links
tips

code
users
tools
tutorials
projects
web
help
design

mudabone
suletzki
trans48
nutrition reality

MarthaAttire!

UDP Sockets Asynch Timeout


This class allows you to monitor an ip:port for an incoming message, times out at a specified time. Let me know if you find it useful or have any questions. wiseleyb@yahoo.com


using System;
using System.Timers;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace CourtLinkData
{
     
     public class udpServerSimple
     {

          // This derived class demonstrate the use of three protected methods belonging to the UdpClient class.
          private class MyUdpClientDerivedClass : UdpClient
          {

               public MyUdpClientDerivedClass(int Port) : base(Port) {}

               public byte[] _receive(ref System.Net.IPEndPoint rEP)
               {
                    Socket s = this.Client;
                    s.Blocking = false;
                    return this.Receive(ref rEP);

               }

               public bool _poll()
               {
                    if (this.Active)
                    {
                         Socket s = this.Client;
                         return s.Poll(1, SelectMode.SelectRead);
                    }
                    else return false;
               }

               public int _available()
               {
                    Socket s = this.Client;
                    int a = s.Available;
                    if(a > 0) dp(a);
                    return a;
               }

               private void dp(object o)
               {
                    System.Diagnostics.Debug.WriteLine(o.ToString());
               }

          }

          public class ListenOnPort
          {
               /// <summary>
               /// The main entry point for the application.
               /// </summary>

               public string HostName = "";
               public string IP = "";
               public int Port = 0;
               public int TimeOut = -1;
               public string LookFor = "";
               public string Response = "";
               
               /// <summary>
               /// Monitors IPandPort for sLookFor for iTimeOutInMinutes.  After creating class
               /// use Run() to start polling.
               /// </summary>
               /// <param name="IPandPort">IP:Port (127.0.0.1:80)</param>
               /// <param name="iTimeOutInMinutes">any int > 0</param>
               /// <param name="sLookFor">string to poll for in ip:port</param>
               public ListenOnPort(string IPandPort, int iTimeOutInMinutes, string sLookFor)
               {
                    this.IP = this.parseOutAddress(IPandPort);
                    this.HostName = Dns.GetHostByAddress(this.IP).HostName;
                    this.Port = this.parseOutPort(IPandPort);
                    this.TimeOut = iTimeOutInMinutes;
                    this.LookFor = sLookFor;
               }
               /// <summary>
               /// Monitors an assigned IP and Port for sLookFor for iTimeOutInMinutes.  After creating class
               /// use Run() to start polling.  When you use this instantiator you can check the HostName, IP and 
               /// Port to see what the code has assigned for values.
               /// </summary>
               /// <param name="IPandPort">IP:Port (127.0.0.1:80)</param>
               /// <param name="iTimeOutInMinutes">any int > 0</param>
               /// <param name="sLookFor">string to poll for in ip:port</param>
               public ListenOnPort(int iTimeOutInMinutes, string sLookFor)
               {
                    this.HostName = Dns.GetHostName();
                    this.IP = Dns.Resolve(this.HostName).AddressList[0].ToString();
                    this.Port = this.getFreePortByHostName(this.HostName);
                    this.TimeOut = iTimeOutInMinutes;
                    this.LookFor = sLookFor;
               }
               /// <summary>
               /// Monitors hostName:port for sLookFor for iTimeOutInMinutes.  After creating class
               /// use Run() to start polling.
               /// </summary>
               /// <param name="IPandPort">IP:Port (127.0.0.1:80)</param>
               /// <param name="iTimeOutInMinutes">any int > 0</param>
               /// <param name="sLookFor">string to poll for in ip:port</param>
               public ListenOnPort(string hostName, int port, int iTimeOutInMinutes, string sLookFor)
               {
                    this.HostName = hostName;
                    this.IP = Dns.GetHostByName(this.HostName).AddressList[0].ToString();
                    this.Port = port;
                    this.TimeOut = iTimeOutInMinutes;
                    this.LookFor = sLookFor;
               }

               /// <summary>
               /// This method is here to support threads... you can run this from a thread and
               /// check the results in the Response property.
               /// </summary>
               public void RunInThread()
               {
                    this.Run();
               }
               /// <summary>
               /// Starts polling public methods ip:port for LookFor for TimeOut # of minutes
               /// </summary>
               /// <returns>LookFor, if found; "Timed Out", if timed out; or exception.message, if an error occurs</returns>
               public string Run()
               {
                    string msg = "";
                    //if a client connects, accept the connection
                    //and return a new socket named socketForClient
                    //while tcpListener keeps listening
               
                    try
                    {
                         dp("listening");

                         msg = ReadFromClient(this.HostName, this.Port, this.TimeOut);
                    
                         dp("Exiting...");
                         
                         if (msg == this.LookFor)
                              return msg;
                         else
                         {
                              if (msg.Trim() == "")
                                   msg = "Timed Out";

                              return msg;
                         }
                    }
                    catch (Exception e)
                    {
                         dp(e.Message);
                         return e.Message;
                    }
               }


               private string ReadFromClient(string host, int port, int iTimeOut)
               {
                    // This constructor arbitrarily assigns the local port number.
                    //               UdpClient udpClient = new UdpClient(11000);
                    MyUdpClientDerivedClass udpClient = new MyUdpClientDerivedClass(port);

                    try
                    {

                         //IPEndPoint object will allow us to read datagrams sent from any source.
                         IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
                         //udpClient.Connect(IPAddress.Any,11000);
     
                         // Blocks until a message returns on this socket from a remote host.
                         string returnData="";
                         // Creates and initializes a DateTimeFormatInfo associated with the en-US culture.
                         int timeout = iTimeOut;
                         int reportInterval = 2;
                         DateTime endtime = System.DateTime.Now.AddMinutes(timeout);
                         DateTime reporttime = System.DateTime.Now.AddSeconds(reportInterval);
                         //DateTime  startTime = System.DateTime.Now;
                         try
                         {
                              //                         udpClient.UsingProtectedMethods();
                              try
                              {
                                   byte[] receiveBytes = udpClient._receive(ref RemoteIpEndPoint); 
                                   returnData = Encoding.ASCII.GetString(receiveBytes);
                              }
                              catch 
                              {
                              }

                              do
                              {
                                   if(udpClient._available() > 0) 
                                   {
                                        byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint); 
                                        returnData = Encoding.ASCII.GetString(receiveBytes);
                                   }
                                   if (System.DateTime.Compare(System.DateTime.Now, reporttime) > 0) 
                                   {
                                        dp(System.DateTime.Now + " Still waiting for '" + this.LookFor + "' on port: " + port.ToString());
                                        reporttime = System.DateTime.Now.AddSeconds(reportInterval);
                                   }
                                   System.Threading.Thread.Sleep(100);
                              }while(returnData == "" && System.DateTime.Compare(System.DateTime.Now, endtime) < 0);
                              // Uses the IPEndPoint object to determine which of these two hosts responded.
                              dp("This is the message you received " +
                                   returnData.ToString());
                              dp("This message was sent from " + RemoteIpEndPoint.Address.ToString() +
                                   " on their port number " + RemoteIpEndPoint.Port.ToString());
                              this.Response = returnData;
                              return returnData;
                         }
                         catch(SocketException se)
                         {
                              dp("saw :" + RemoteIpEndPoint.Address + " " + se.ToString() );
                              this.Response = se.ToString();
                              return se.ToString();
                         }
                         finally
                         {
                              udpClient.Close();
                              udpClient = null;
                         }
                    }  
                    catch (Exception e ) 
                    {
                         dp(e.ToString());
                         this.Response = e.ToString();
                         return e.ToString();
                    }


               }

               private int getFreePortByIPAddress(string ip)
               {
                    TcpListener tcpListener = new TcpListener(System.Net.IPAddress.Parse(ip),0);
                    return getFreePort(tcpListener);
               }
               private int getFreePortByHostName(string hostName)
               {
                    TcpListener tcpListener = new TcpListener(Dns.Resolve(hostName).AddressList[0],0);
                    return getFreePort(tcpListener);
               }
               private int getFreePort(TcpListener tcpListener)
               {
                    tcpListener.Start();
                    string address = tcpListener.LocalEndpoint.ToString();
                    tcpListener.Stop();
                    tcpListener = null;
                    return parseOutPort(address);
               }
               private int parseOutPort(string IPandPort)
               {
                    return Convert.ToInt32(IPandPort.Substring(IPandPort.IndexOf(":")+1));
               }
               private string parseOutAddress(string IPandPort)
               {
                    return IPandPort.Substring(0,IPandPort.IndexOf(":"));
               }

               private void dp(object o)
               {
                    System.Diagnostics.Debug.WriteLine(o.ToString());
               }
          }

     }
}


Last Modified 3/2/04 3:02 PM

Hide Tools