Object References…
by Dean Thomas on Dec.20, 2008, under .NET
Usually in .NET, any object i instantiate i keep a reference to it until i don’t need it anymore, which is a common thing with any programming language. However, there are times when you don’t need a reference, you just want to call something and not care about the object. Which is what happened.
Basically the scenario is, i had a windows service that runs 24/7 which does data importing every x hours, with a number of data providers setup, all having their own times to import the data. And every 10 minutes, a thread is created to check to see if anything needs to be run, if it does, it runs it, if not then it just sleeps for 10 minutes again.
Now instead of actually calling a Thread.Sleep(10000), i figured it would make sense to use a Timer from the Diagnostics namespace, because i could say, in 10 minutes, call method X. Which was perfect! And it worked a treat. Sometimes.
All through development it was fine, through testing was fine (got very lucky, i guess) and then it went live, for the first few days it was fine (we were updating it quite alot so stopping-starting the serivce). Then it hit the weekend, come back monday morning, nothing. No imports since friday at 9pm. What the…?
Hunted through the code, nothing. It made NO sense that the data wasn’t importing, all the logic was there, i even called the other guys round for an idiot check. No-one could see the problem. So i thought, maybe an exception isn’t bubbling up correctly and we’re not getting it logged… Threw a whole host of extra debug logging in and re-deployed the service…sure enough, same thing happened again.
After about 30 minutes of reading up on the timer class, i realise 2 things.
1) It has a dispose method. Which means i should always have a reference to it, because when i’ve finished with it, i need to dispose of it.
2) MSDN is always the last place i look, but always has the answer. Why don’t i ever look there first?!
As it turns out, because the garbage collector in .NET (and rightly so) comes and clears memory when it wants to, any objects that don’t have a reference, will get nuked. Which is exactly what was happening. We were setting the timer, then sometimes, .NET was coming along and clearing it because we had no reference to it. Therefore preventing the importers from running, and the service of course was still running…but not actually doing anything as the main timer’d thread was killed off.
Now i have a member of the class which has a reference, and i dispose of it when the service stops/restarts.
It’s really weird, i knew .NET did that, but it didn’t even occur thats what could be happening. But, we all learn from our mistakes!
So, Keep a reference to your objects and make sure you dispose of them when your done! Don’t make the mistake i did…
PHP, WMI, COM (How many more abbreviations can i get?)
by Dean Thomas on Dec.14, 2008, under PHP
Well, to start with, apologies for the title line… why is everything abbreviated when it comes to computers? I guess it can’t do my SEO work any harm, right?
Anyway, back to something meaningful.
I’ve begun writing a little DNS Manager in PHP, that runs on an IIS 6/7 web server. Initially i was going to write this in .NET as it has alot of support for WMI out of the box, using the ManagementObject classes. But i work in ASP.NET for 40 hours (at least) a week, i like to play with different languages. (IIS 7 + Windows Server 2008 + PHP 5 - http://www.waxer.nl/?p=72)
So, first off, how do we use COM in PHP? Fairly straight forward it would appear.
<?php $comObject = new COM ("WbemScripting.SWbemLocator"); ?>
Thats it. I now have a COM object loaded up into my variable. It’s nice to see that it’s just as easy if i was using say VBScript to accomplish this task.
So, now i want to connect to the DNS Service, so that i can list all of the zones i currently have setup. Again, a resonably simple task, using my above $comObject i can connect, and iterate through all DNS Zones.
<?php /*Connect to the DNS Server, first param is the Host, second is the Namespace, third is the username, fourth is the password (the last two are only required for a remote machine)*/ $dnsService = $comObject->ConnectServer('localhost', 'rootMicrosoftDNS', '', ''); //Loop through every instance of the class MicrosoftDNS_Zone in our DNS Service. foreach ($dnsService->InstancesOf("MicrosoftDNS_Zone") as $existingZone) { //For now, just echo it's name, just so we can see what Zones we have setup. echo 'Zone Name: ' . $existingZone->Name; } ?>
And thats, it, this is how we can show all of the zones inside a Microsoft DNS Server.
As you can see, we call an InstancesOf method inside our $dnsService variable, this does exactly what it says on the tin. It returns an array of ALL the specified instances inside this object. Which is great, because we can also call the same method to return all instances of A Records, or SOA Records. Which is very handy for writing a DNS Management portal!
The MicrosoftDNS_Zone is a class, that is provided by the WMI service in WIndows, if you follow the link provided, you can see all of it’s members, these are ALL fields we can view. You will also notice that the MicrosoftDNS_Zone class has a number of methods available to it too.
I will provide another blog on how to create/delete zones in your Microsoft DNS Server!
Sun’s VirtualBox Networking (Ubuntu 64Bit Intrepid Ibex)
by Dean Thomas on Dec.14, 2008, under Ubuntu
Recently i started a little PHP Project, where i wanted to manage Microsofts DNS server via a nice little web interface, of course i would have to use COM Object for this.
So, first off, i needed a Windows Server machine… a friend told me that VMWare Server was free to use, so i grabbed it. That turned out to be a dead end, after installation it just hung my PC (Running server 2003 or 2008) so i removed that, and installed Virtual Box. It’s great, simple to use (more like VMWare Workstation, whcih didn’t work either.) and fast, which is just what i was after.
# wget http://download.virtualbox.org/virtualbox/2.0.6/virtualbox-2.0_2.0.6-39765_Ubuntu_intrepid_amd64.deb # sudo ipkg --install virtualbox-2*.deb
And that was it, VirtualBox installed and ready to run. All seemed too easy. Why wasn’t VMWare this easy?

VirtualBox Main Window
As you can see, i’ve taken this screenshot after i’ve got an installed version of 2008 running. All you have to do is click New, follow the few simple steps, mount your CD/DVD and click run. That really is it. Follow the install instructions, and within ~30mins you should have a full Windows 2008 VM Running.
Now i came across a slight issue. The network configuration defaults to NAT Type, which is fine for most. As it uses your PC’s connection for it’s network, so you have an internal IP address. You will be able to connect to the internet (as it’s routed through your PC - The host). But, the internet will not be able to connect to you. I needed to be able to view my IIS Server remotely, from another machine across the globe.
So to do this, the network has to be setup as ‘Host Interface’, which means you can use an interface from the host machine. So, we also need to create a new host on the virtual machine, which will bridge between eth0 (eth0 in my case, could be ethX for you).
This is how your Network pane should look.

tap0 is the device name we need to create, which can be done by create a simple bash script that creates the new device, sets up the bridge between your ethX and the tap0 and then gets an IP Address for the tap0 device.
#!/bin/bash #$1 = Username #$2 = Local Device #$3 = EthX IP Address #$4 = Tap0 IP Address sudo tunctl -t tap0 -u $1 sudo chmod 666 /dev/net/tun sudo /usr/sbin/brctl addbr br0 sudo /sbin/ifconfig eth0 0.0.0.0 promisc sudo /usr/sbin/brctl addif br0 $2 sudo /sbin/dhclient br0 sudo /usr/sbin/brctl addif br0 tap0 sudo ifconfig tap0 $4 up sudo bash -c 'echo 1 > /proc/sys/net/ipv4/conf/tap0/proxy_arp' sudo route add -host $3 dev tap0 sudo arp -Ds $3 $2 pub
Save this as createbridge.sh.
This script requires 4 parameters, your local username (in my case it was dean ;)), the local device you want to bridge (eth0 for me), the IP address of your eth0 device (192.168.1.100 for me) and the IP Address you want the tap0 device to get (i chose 192.168.1.200), i call it like this when i log onto my machine.
# sh createbridge.sh dean eth0 192.168.1.100 192.168.1.200
Wait for it to finish, then you should have a new br0 device which is the bridge which will have the IP Address of your ethX device. You should also have a new device called tap0 which will have the IP Address you specified, mine being 192.168.1.200.
And that is it, i fired up my VM, straight into Windows, instantly viewable from the network and the internet. Perfect!
Hope this helps people that had the same problem.
Music Aggregator!
by Dean Thomas on Mar.08, 2008, under Uncategorized
Hey anyone who actually reads this.
I’m sick of searching for a music video, or trying to find lyrics without getting innundated with my web browser making noises and slowing down because annoying popups want to abuse my machine. So this project (side project, not spending much time on it…) is gunna fix all my issues.
With an AmazonAPI Hooked in, i can search for artists. I’m in the process of writing a Lyrics web scraper and after that is videos (YouTube, etc) so that i can have all the info i need about a band in one place. Google is a wonderful thing, but everything in one place is much more efficient.
Anywho, here is the current url (Removed) it doens’t do much except cache the results, as the AmazonAPI has restrictions on how often i can speak to them (1 hit per second) it’s better i cache the results as it’ll speed up the search and prevent Amazon removing my account.
If anyone could just type in a few random bands, i would be greatful. I just need the content then i can have a bigger website, community driven effectively.
I don’t want to hear about bugs, crashes, slowness, this is so far from being ready it’s not true. But you can never have enough content, hence the release.
I will be writing a simple MP3 Tag Reader that’ll run through my collection of music, populating the DB too, should anyone be interested in devoting some time to running an app through their collection i will be greatful (just leave a comment). Sourcecode will be released with of course to prove i’m not about to chuck a worm onto your machine.
Cheers!
Dean
Usenet ReadLine()
by Dean Thomas on Feb.12, 2008, under Uncategorized
Ever tried writing a Usenet client before? Even a simple little one that just downloads an image from your favourite group.
Well, it can be a pain. The spec is simple enough, everything is explained well in the 2 RFCs. But a couple of things weren’t so clear when i started.
First off, the curse of the double dot. For most Usenet calls (Body, Head, etc) its way of notifying you that it has finished sending you data, is to send you a ‘.’. Which is great, nice simple way to let me know that you have finished sending me the information.
However, when you receive a file from usenet, you tend to do it line by line, so you can check for such an end of message. But what if your line of data starts with a ‘.’ because, well it just might. It just adds another ‘.’, so it now becomes ‘..’ which is fine, because i know it’s not the end of the message, and i can just carry on as normal. Do NOT forget to remove one of those ‘.’ otherwise your file will appear as ‘corrupt’ even though it may only be one byte at the end.
Secondly, the encoding. I spent ages trying to figure out why my files were completely different to what they should be, and why my results werent matching up with what say Outlook express could return me. For those of you that didn’t know, Outlook express is a pretty neat Usenet client, terrible as an email client however.
Anywho, usenet files are posted as iso-8859-1, so any file saving that gets done, MUST use that encoding, or again corruption. Imagine not removing a . and saving with the wrong encoding, thats a fun debugging session.
Well, i have attached a sample function that will read a line response from Usenet, and return it as a string (iso-8859-1). It handles the double dot, at the end of the function as you can see.
I Hope this helps someone and saves them more problems than i had…
D
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | public string ReadLine() { ArrayList returnedBytes = new ArrayList(); byte[] previousByte = new byte[1]; byte[] thisByte = new byte[1]; NetworkStream reader = ServerConnection.GetStream(); while (true) { //Read a byte, check it int received = reader.Read(thisByte, 0, 1); //Check the byte, let's see what it is... if (received == 1) { bool addByte = false; bool endOfLine = false; //Check if we have a previous byte switch ((char)previousByte[0]) { case '\r'://Ignore this byte, it's probably a \n addByte = true; break; default: //No previous byte addByte = true; break; } //Check for New Line if ((char)thisByte[0] == '\n' && (char)previousByte[0] == '\r') { endOfLine = true; } //Set the previous byte previousByte[0] = thisByte[0]; //Add this byte? if (addByte) returnedBytes.Add(thisByte[0]); //Is this the end of the line? if (endOfLine) break; } else { break; } } Encoding usenetEncoding = Encoding.GetEncoding("iso-8859-1"); string finalLine = usenetEncoding.GetString((byte[])returnedBytes.ToArray()); if (finalLine.StartsWith("..")) finalLine = finalLine.Remove(0, 1); return finalLine; } |