Pinging Another Computer Using C#

There are times when I need to know when a server goes down. Or sometimes I just want to know why the hell I can't read Saturday Morning Breakfast Cereal in the morning (or for that matter, XKCD). So a while ago I created a bit of code that would ping a server. By the way, when you ping another computer what you're really doing is using the echo function of the Internet Control Message Protocol. The nice thing about it is that it's extremely simple to implement.

    /// <summary>
    /// Class used to ping another computer
    /// </summary>
    public static class Ping
    {
        #region Public Static Functions

        /// <summary>
        /// Does a ping against the host specified
        /// </summary>
        /// <param name="Address">Address of the host</param>
        /// <returns>True if a response is received, false otherwise</returns>
        public static bool PingHost(string Address)
        {
            IPHostEntry Server, From;
            Socket Socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
            Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 1000);
            try
            {
                Server = Dns.GetHostEntry(Address);
                From = Dns.GetHostEntry(Dns.GetHostName());
            }
            catch (Exception)
            {
                Socket.Close();
                throw new Exception("Can't find host");
            }

            EndPoint EndPoint = new IPEndPoint(Server.AddressList[0], 0);
            EndPoint EndPointFrom = new IPEndPoint(From.AddressList[0], 0);

            int PacketSize = 40;
            Packet Packet = new Packet();
            Packet.Type = 8;
            Packet.SubCode = 0;
            Packet.Check = 0;
            Packet.ID = 45;
            Packet.SequenceNumber = 0;
            int DataSize = 32;
            Packet.Data = new byte[DataSize];
            for (int x = 0; x < DataSize; ++x)
            {
                Packet.Data[x] = (byte)'#';
            }
           
            byte[] Buffer = Serialize(PacketSize, Packet);
            double CheckSumSize=System.Math.Ceiling((double)PacketSize/2);

            ushort []CheckSumBuffer=new ushort[(int)CheckSumSize];
           
            int BufferIndex=0;
            for(int x=0;x<(int)CheckSumSize;++x)
            {
                CheckSumBuffer[x]=BitConverter.ToUInt16(Buffer,BufferIndex);
                BufferIndex+=2;
            }
            Packet.Check = CheckSum(CheckSumBuffer);

            Buffer = Serialize(PacketSize, Packet);

            if (Socket.SendTo(Buffer, PacketSize, 0, EndPoint) == -1)
            {
                Socket.Close();
                throw new Exception("Couldn't send packet");
            }
            Buffer=new byte[256];
            int NumBytes = Socket.ReceiveFrom(Buffer, 256, SocketFlags.None, ref EndPointFrom);
            if (NumBytes == -1)
            {
                Socket.Close();
                throw new Exception("Host not responding");
            }
            else if (NumBytes > 0)
            {
                Socket.Close();
                return true;
            }

            Socket.Close();
            return false;
        }

        #endregion

        #region Private Static Functions

        /// <summary>
        /// Does a check sum of an array
        /// </summary>
        /// <param name="CheckSumBuffer">Buffer to do a check sum on</param>
        /// <returns>The check sum of the buffer</returns>
        private static ushort CheckSum(ushort[] CheckSumBuffer)
        {
            Int32 Sum = 0;
            for (int x = 0; x < CheckSumBuffer.Length; ++x)
            {
                Sum += Convert.ToInt32(CheckSumBuffer[x]);
            }
            Sum = (Sum >> 16) + (Sum & 0xffff);
            Sum += (Sum >> 16);
            return (UInt16)(~Sum);
        }

        /// <summary>
        /// Serializes the packet into an array
        /// </summary>
        /// <param name="PacketSize">Size of the packet</param>
        /// <param name="Packet">Packet to serialize</param>
        /// <returns>The packet in byte array form</returns>
        private static byte[] Serialize(int PacketSize, Packet Packet)
        {
            byte[] Buffer = new byte[PacketSize];
            int x = 2;
            Buffer[0] = Packet.Type;
            Buffer[1] = Packet.SubCode;

            byte[] TempArray = BitConverter.GetBytes(Packet.Check);
            Array.Copy(TempArray, 0, Buffer, x, TempArray.Length);
            x += TempArray.Length;

            TempArray = BitConverter.GetBytes(Packet.ID);
            Array.Copy(TempArray, 0, Buffer, x, TempArray.Length);
            x += TempArray.Length;

            TempArray = BitConverter.GetBytes(Packet.SequenceNumber);
            Array.Copy(TempArray, 0, Buffer, x, TempArray.Length);
            x += TempArray.Length;

            Array.Copy(Packet.Data, 0, Buffer, x, Packet.Data.Length);

            return Buffer;
        }

        #endregion

        #region Private Classes

        /// <summary>
        /// Acts as a packet holder
        /// </summary>
        private class Packet
        {
            public byte Type;
            public byte SubCode;
            public ushort Check;
            public ushort ID;
            public ushort SequenceNumber;
            public byte[] Data;
        }

        #endregion
    }

It's a decent amount of code but basically all you are doing is creating a Packet object and filling it out with basic information, the request type, sub code, ID, etc. Once that is done you serialize it into a byte array. You may be asking why I'm not using the .Net serialization. Well it doesn't quite work the way that you would expect, so it's just best to write another function to do it. After you serialize it, you need to do a check sum on it. Then store that in the packet and then finally serialize it again before sending it to the server. But after that you just wait for a response. If you get the response, yay it's up. Otherwise it's down (or not accepting pings which is a possibility). Anyway, that's it. Or of course you could just use the Ping class that microsoft has built into .Net. You may be curious why I didn't mention it earlier. The Ping class wasn't added until 2.0 and my original code (although it's been updated) was created back in 1.1... Anyway, try it out, leave feedback, and happy coding.

kick it on DotNetKicks.com   Shout it
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkListEmail

Posted by: James Craig
Posted on: 10/29/2009 at 1:05 PM
Tags: , , , ,
Categories: C#
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Priority Queue in C#

This is simply one of my many data type posts. Not the most interesting of subjects, but hey it might help someone out. Anyway, I created a sort of distributed message based event system for a project that I was working on. Some messages/events were a bit more important than others and they were coming in faster than the system could handle so I figured that what was needed was a priority queue. A priority queue is basically a queue, first in first out, data type but items are prioritized. So an item with a lower priority will be returned after something of a higher priority but will be returned in the order it was recieved when compared to items of the same priority... Really you can think of this as a set of queues, one for each priority level. We start the highest priority and work our way down. And if none of that made sense (since I'm writing it, I give it a 50/50 chance that it didn't), you can read about them a bit more here. Anyway, I went ahead and implemented my own version since .Net only has your basic queue:

    /// <summary>
    /// Helper class that implements a priority queue
    /// </summary>
    /// <typeparam name="T">The type of the values placed in the queue</typeparam>
    public class PriorityQueue<T>:ListMapping<int,T>
    {
        #region Constructor

        /// <summary>
        /// Constructor
        /// </summary>
        public PriorityQueue()
            : base()
        {
        }

        #endregion

        #region Public Functions

        /// <summary>
        /// Peek at the next thing in the queue
        /// </summary>
        /// <returns></returns>
        public virtual T Peek()
        {
            if (Items.ContainsKey(HighestKey))
            {
                return Items[HighestKey][0];
            }
            return default(T);
        }

        public override void Add(int Priority, T Value)
        {
            if (Priority > HighestKey)
                HighestKey = Priority;
            base.Add(Priority, Value);
        }

        /// <summary>
        /// Removes an item from the queue and returns it
        /// </summary>
        /// <returns>The next item in the queue</returns>
        public T Remove()
        {
            T ReturnValue=default(T);
            if (Items.ContainsKey(HighestKey)&&Items[HighestKey].Count >= 1)
            {
                ReturnValue = Items[HighestKey][0];
                Items[HighestKey].Remove(ReturnValue);
                if (Items[HighestKey].Count == 0)
                {
                    Items.Remove(HighestKey);
                    HighestKey = int.MinValue;
                    foreach (int Key in Items.Keys)
                    {
                        if (Key > HighestKey)
                            HighestKey = Key;
                    }
                }
            }
            return ReturnValue;
        }

        #endregion

        #region Protected Variables

        protected int HighestKey = int.MinValue;

        #endregion
    }

The code above is not the fastest out there but it gets the job done. It should be fairly straight forward but just know that the priority goes up, so 9 is a higher priority than 1. Also you may be wondering what the hell the ListMapping class is. It's another one of my classes from the utility library.  But the code for it can be found below:

    /// <summary>
    /// Maps a key to a list of data
    /// </summary>
    /// <typeparam name="T1">Key value</typeparam>
    /// <typeparam name="T2">Type that the list should contain</typeparam>
    public class ListMapping<T1,T2>
    {
        #region Constructors

        /// <summary>
        /// Constructor
        /// </summary>
        public ListMapping()
        {
        }

        #endregion

        #region Private Variables

        protected Dictionary<T1, List<T2>> Items = new Dictionary<T1, List<T2>>();

        #endregion

        #region Public Functions

        /// <summary>
        /// Adds an item to the mapping
        /// </summary>
        /// <param name="Key">Key value</param>
        /// <param name="Value">The value to add</param>
        public virtual void Add(T1 Key, T2 Value)
        {
            try
            {
                if (Items.ContainsKey(Key))
                {
                    Items[Key].Add(Value);
                }
                else
                {
                    Items.Add(Key, new List<T2>());
                    Items[Key].Add(Value);
                }
            }
            catch { throw; }
        }

        /// <summary>
        /// Determines if a key exists
        /// </summary>
        /// <param name="key">Key to check on</param>
        /// <returns>True if it exists, false otherwise</returns>
        public virtual bool ContainsKey(T1 key)
        {
            try
            {
                return Items.ContainsKey(key);
            }
            catch { throw; }
        }

        /// <summary>
        /// The list of keys within the mapping
        /// </summary>
        public virtual ICollection<T1> Keys
        {
            get { try { return Items.Keys; } catch { throw; } }
        }

        /// <summary>
        /// Remove a list of items associated with a key
        /// </summary>
        /// <param name="key">Key to use</param>
        /// <returns>True if the key is found, false otherwise</returns>
        public virtual bool Remove(T1 key)
        {
            try
            {
                return Items.Remove(key);
            }
            catch { throw; }
        }

        /// <summary>
        /// Gets a list of values associated with a key
        /// </summary>
        /// <param name="key">Key to look for</param>
        /// <returns>The list of values</returns>
        public virtual List<T2> this[T1 key]
        {
            get
            {
                return Items[key];
            }
            set
            {
                Items[key] = value;
            }
        }

        /// <summary>
        /// Clears all items from the listing
        /// </summary>
        public virtual void Clear()
        {
            Items.Clear();
        }

        /// <summary>
        /// The number of items in the listing
        /// </summary>
        public virtual int Count
        {
            get { return Items.Count; }
        }


        #endregion
    }

Basically all the code does, is map a key (in this case an integer/priority) to a list of items. It's sort of like a dictionary object but allows you to add the same key multiple times and it simply adds it to the list. That being said, it shouldn't be too difficult to figure them out. So try them out, leave feedback, and happy coding.

kick it on DotNetKicks.com   Shout it
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkListEmail

Posted by: James Craig
Posted on: 10/27/2009 at 11:29 AM
Tags: , , ,
Categories: C#
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Searching Craigslist Using C#

I'm sort of all over the place with my projects as of late. But along with the Hulu, Netflix, etc. search functions, I wanted to be able to search other sites. One of these sites is Craigslist. I don't search it that often but it is one of those sites that I hit from time to time. So I figured how hard could it be to search it? Not that difficult it turns out:

    /// <summary>
    /// Craigslist helper
    /// </summary>
    public static class Craigslist
    {
        #region Public Static Functions

        /// <summary>
        /// Searches craigslist
        /// </summary>
        /// <param name="Site">Site to search (for instance http://charlottesville.craigslist.org/ for Charlottesville, VA)</param>
        /// <param name="Category">Category to search within</param>
        /// <param name="SearchString">Search term</param>
        /// <returns>RSS feed object</returns>
        public static Document Search(string Site, Category Category, string SearchString)
        {
            return new Document(Site + "/search/" + Names[(int)Category] + "?query=" + HttpUtility.UrlEncode(SearchString) + "&catAbbreviation=" + Names[(int)Category] + "&minAsk=min&maxAsk=max&format=rss");
        }

        #endregion

        #region Private Static Variables

        /// <summary>
        /// Abbreviations for categories that Craigslist uses
        /// </summary>
        private static string[] Names ={"sss","art","pts","bab","bar","bik","boa","bks","bfs","cta","ctd",
            "cto","emd","clo","clt","sys","ele","grd","zip","fua","fud","fuo","tag","gms","for","hsh",
            "wan","jwl","mat","mcy","msg","pho","rvs","spo","tix","tls"};

        #endregion
    }

    #region Enum

    /// <summary>
    /// Category to search within
    /// </summary>
    public enum Category
    {
        All_For_Sale,
        For_Sale_Arts_Crafts,
        For_Sale_Auto_Parts,
        For_Sale_Baby_Kid_Stuff,
        For_Sale_Barter,
        For_Sale_Bicycles,
        For_Sale_Boats,
        For_Sale_Books,
        For_Sale_Business,
        For_Sale_Cars_And_Trucks_All,
        For_Sale_Cars_And_Trucks_Dealer,
        For_Sale_Cars_And_Trucks_Owner,
        For_Sale_CDs_DVDs_VHS,
        For_Sale_Clothing,
        For_Sale_Collectibles,
        For_Sale_Computers_Tech,
        For_Sale_Electronics,
        For_Sale_Farm_Garden,
        For_Sale_Free_Stuff,
        For_Sale_Furniture_All,
        For_Sale_Furniture_By_Dealer,
        For_Sale_Furniture_By_Owner,
        For_Sale_Games_Toys,
        For_Sale_Garage_Sales,
        For_Sale_General,
        For_Sale_Household,
        For_Sale_Items_Wanted,
        For_Sale_Jewelry,
        For_Sale_Materials,
        For_Sale_Motorcycles,
        For_Sale_Musical_Instruments,
        For_Sale_Photo_Video,
        For_Sale_Recreational_Vehicles,
        For_Sale_Sporting_Goods,
        For_Sale_Tickets,
        For_Sale_Tools
    }

    #endregion

Note that there are other sections to craigslist, but I really only look for things being sold (although I did manage to find my current job through the site). But basically you just need to enter in the individual site (since they have about 10,000 of them), the category you want to search in, and the search term. In return you're given a RSS Document object. Note that this is a slightly modified version of my RSS helper that can be found in my utility library). The reason it's modified is that Craigslist doesn't do a normal RSS feed. Instead they use RDF with RSS elements... The only main difference, in terms of code, from the version that is currently in the utility library is in the Document class itself. Specifically the constructor:

public Document(string Location)
        {
            try
            {
                XmlDocument Document = new XmlDocument();
                Document.Load(Location);
                foreach (XmlNode Children in Document.ChildNodes)
                {
                    if (Children.Name.Equals("rss", StringComparison.CurrentCultureIgnoreCase))
                    {
                        foreach (XmlNode Child in Children.ChildNodes)
                        {
                            if (Child.Name.Equals("channel", StringComparison.CurrentCultureIgnoreCase))
                            {
                                Channels.Add(new Channel((XmlElement)Child));
                            }
                        }
                    }
                    else if (Children.Name.Equals("rdf:rdf", StringComparison.CurrentCultureIgnoreCase))
                    {
                        List<Item> Items = new List<Item>();
                        foreach (XmlNode Child in Children.ChildNodes)
                        {
                            if (Child.Name.Equals("channel", StringComparison.CurrentCultureIgnoreCase))
                            {
                                Channels.Add(new Channel((XmlElement)Child));
                            }
                            else if (Child.Name.Equals("item", StringComparison.CurrentCultureIgnoreCase))
                            {
                                Items.Add(new Item((XmlElement)Child));
                            }
                        }
                        if (Channels.Count > 0)
                        {
                            Channels[0].Items = Items;
                        }
                    }
                }
            }
            catch { }
        }

I'm not that happy with the way that ends up but it is what it is. Other than that though, It's pretty simple to use. But if you want to use your own RSS parser, it shouldn't be too difficult to write. Especially considering it's not exactly an RSS feed. Anyway, try it out, leave feedback, and happy coding.

kick it on DotNetKicks.com   Shout it
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkListEmail

Posted by: James Craig
Posted on: 10/22/2009 at 10:53 AM
Tags: , , ,
Categories: C#
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed