Holy Smokes!

Tuesday, November 18, 2008

Super Crazy Linux Week

Well, not Super Crazy... but fun just the same.  Just this last week, I dug out my old laptop, and installed Linux on it.  Fedora Core 9 actually.  It's been fun...

Why would I do such a thing?  Well it started off as boredom,  I just wanted to.  Besides, the laptop wasn't being used for anything.

Once I got it set up, I started playing with mono.  For those of you who are still actually unaware of what mono is, it's an open source Microsoft .NET compliant framework.  Although my super technical definition may not be 100% accurate, you might want to look it up on wikipedia, or on the mono project homepage.

The last time I had played with mono was about 2 years ago.  And I have to tell you, I am very impressed with what I have seen this week.  I was able to compile a relatively complicated project built to run in Visual Studio 2008, for .NET 2.0.  While it did not execute exactly as expected, the areas it lacked were really not a big deal, and I was able to find ways around each and every issue I have faced so far.

My biggest complaint with Fedora Core, was the fact that the package manager did not have access to the most recent versions of the mono tools, and I had a great deal of difficulty compiling the latest to make it run on Fedora Core 9.  So my task now is to find the most perfect "out of the box" distribution for mono.

I installed Ubuntu to start my search.  The results weren't bad, but I totally missed the obvious.  I'm probably looking for OpenSUSE or SLES, since Novell is sponsoring the development of mono.  I'm burning OpenSUSE to DVD right now...

Anyways, out of the box, Ubuntu was a lot lighter weight, and more graphically appealing.  But how would it fare with immediate mono support.  Not bad actually.  I did have to add the 'universe' repository to the package manager, but I was able to get the most recent version of mono develop and a somewhat recent version of the framework up and running, and with just a few clicks of the mouse.

My beef with Ubuntu, is that the ASP.NET functionality did not work out of the box when I set it up in this way.  The updates also took significantly longer to apply with Ubuntu.

So tonight, I am going to try out OpenSUSE, and I'll post my results here.  If anyone has any opinion on the matter, or any good/bad experiences working with mono, I'd love to hear about it.

Saturday, November 8, 2008

"Traditional Sockets" in .NET -- Part 2

The other day I started talking about sockets in .NET. The whole reason this has been on my mind is because I have been discussing them with a coworker of mine. In Part 1 we created a simple server that would allow a telnet client to connect, the server would transmit a simple text message, and the server would terminate. Creating a simple client is not an awful lot different than creating a server. So I will just assume you have saved your Server project. If not, the code can be copy/pasted in part 1. Ok, you have your Server again? Great. We need to create a new project for the client. We can either do this in a new solution, in the usual way, or we can do this in the same solution. Keep in mind that if you choose to do your client in a new solution, any time I say run solution, I mean run the server, then the client. If you choose to add the client project to the current solution, Locate the solution node in the Solution Explorer Treeview Control, as seen here. The idea is that you need to right click this Solution Node to bring up a context menu, locate a sub menu called "Add", and in the sub menu select "Project". Creating this project is not an awful lot different than creating any other project. It will bring up a project template selection window, I would just select another Console application. The only trick once this project is selected, is to ensure that both the Client and the Server are starting at the same time. This can be accomplished by right clicking on that same Solution Node, to bring up a context menu, and by selecting properties on that context menu. This will bring up the solution Properties dialog. I have already set the properties properly. You want to chance the radio button selection from 'Single' or 'Current' to 'Multiple'. Then you want to choose 'Start' in both projects. Lastly, you want to make sure the Server is starting first. You can do this by selecting a project in the grid, and using the arrow buttons on the side. Once that is done, you can hit OK. Now we can move on making the client connect to the server. So make sure the source window for Program .cs in the Client project is open for editing. And make sure again that you are importing from the Networking Namespace and the Socket Namespace.
using System;
using System.Net;
using System.Net.Sockets;



Now move down to the Main function. I told you that we would define a socket in the client application in a very similar way. When we construct the socket, we are defining how the socket is going to behave, and this is highly important. So why don't we start with pretty well the same line of code, except that we will give it a more convincing name.

Socket socketClient =
new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
 

Looks similar right? That's good, because it should. Now if we think about the terminology, A Server Accepts connections from clients, whereas a client Connects to a server. You will notice that a member function for socketClient exists called Connect. Connect


is a little more complicated than Accept, in that it actually takes a parameter. You will notice that the parameter it expects is an EndPoint. Do you remember that an EndPoint on the server was basically an IP address and a Port? I hope your connecting the dots. What do you suppose would happen if we supplied an endpoint, that described a location where the server was listening for connections. I believe we specified the last endpoint as..
IPEndPoint epLocal = new IPEndPoint(IPAddress.Any, 13001);


Oh but wait. We had decided to use the IPAddress.Any constant. We actually need to give it an address. If I were to leave you ponder about this for a while, or to try and make an address fit in there, you might eventually come to realize that even though IP addresses have numbers in them, as we generally express them, they are actually strings. So are web addresses. The string notation, 192.168.1.1 is expressed that way for a lot of reasons. Most of which is very much out of scope of this tutorial. In .NET, an address is a long number. You cant just plug in 192.168.1.1. And of course we cannot plug in www.google.com. Instead we use a facility called DNS (Domain Name System.) And while an IP notated string does not need to be looked up, it can be translated, an address like www.google.com would certainly have to be looked up. Luckily in .NET we can use the very same facility to look up either.
Dns.GetHostEntry("127.0.0.1");
Dns.GetHostEntry(www.google.com);


Very straight forward right? Good. Now also keep in mind that a lookup can return more than one IP address, or none. It's a great idea to make sure you are testing the output from such a lookup. We will not. This example is so simple, that not much will go wrong, and I will get into more detail if someone really wants to know. So lets create an EndPoint that can locate the server.
IPEndPoint epRemote =
new IPEndPoint(Dns.GetHostEntry("127.0.0.1").AddressList[0], 13001);


I of course renamed the IPEndPoint to make a little more sense. But now we can complete our connection. Why don't you make your Main function look something like this.
static void Main(string[] args) {
IPEndPoint epRemote =
new IPEndPoint(Dns.GetHostEntry("127.0.0.1").AddressList[0], 13001);
Socket socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socketClient.Connect(epRemote);

return;
}


You could technically run this, and it would probably execute so quickly that you would have not much idea anything happened. If it worked correctly, both the server and the client consoles would open then close. Now I will interrupt here for a second. Because there is a possibility that this will not work. Especially if you are using Vista. Vista configurations that I have seen have IPV6 support enabled. And when we do a look up, the GetHostEntry will return multiple addresses. If the first address that is returned is IPV6, then you will get an error indicating that the address is incompatible with the protocol. If you get this message, you can use the immediate window to locate the proper index, or you can just keep incrementing the index until it works. If anyone has any issues with that, I will gladly provide more insight. Moving along. So why did we not see the text in the client? You might be thinking the window closed to fast to read it. That's not the only reason you didn't see anything. But for now, lets solve that problem. Place this snippit in the bottom of both the client and the server.
Console.WriteLine("Press  to terminate");
Console.ReadLine();

Your code in the server should look like this:

static void Main(string[] args) {
IPEndPoint epLocal = new IPEndPoint(IPAddress.Any, 13001);

Socket socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socketServer.Bind(epLocal);
socketServer.Listen(4);
Socket socketClient = socketServer.Accept();

byte[] bytSend = System.Text.ASCIIEncoding.ASCII.GetBytes("Hello, World!");
socketClient.Send(bytSend, 0, bytSend.Length, SocketFlags.None);

Console.WriteLine("Press to terminate");
Console.ReadLine();

socketClient.Close();
socketServer.Close();
}


And your code in the client should look like this:

static void Main(string[] args) {
IPEndPoint epRemote = new IPEndPoint(Dns.GetHostEntry("127.0.0.1").AddressList[2], 13001);
Socket socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socketClient.Connect(epRemote);

Console.WriteLine("Press to terminate");
Console.ReadLine();

return;
}


Try running the solution again. Both consoles stay open, but you only see the Message indicating that you can hit the enter key to terminate right? So why is it that the Telnet window gets the message, and our client does not. We do know that the client is connecting, because if you never ran the client, the server window would stay black, and you would get no Press Enter Message. Then if you attempted to connect with telnet again, you would get the expected result. The answer is simpler than you might think, or maybe I'm not giving you enough credit. Sockets work very similarly to working with files, or working with standard input / output. The truth is the client has in fact received the data, we just haven't read it out of the buffers yet. Why not add a read and print statement to the client.
static void Main(string[] args) {
IPEndPoint epRemote = new IPEndPoint(Dns.GetHostEntry("127.0.0.1").AddressList[2], 13001);
Socket socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socketClient.Connect(epRemote);

byte[] bytRecv = new byte[13];
socketClient.Receive(bytRecv, 0, bytRecv.Length, SocketFlags.None);
Console.WriteLine(System.Text.ASCIIEncoding.ASCII.GetString(bytRecv, 0, bytRecv.Length));

Console.WriteLine("Press to terminate");
Console.ReadLine();

return;
}


Ok, there are a few things happening here. Again, I am making a byte array, and I am running a similar operation off of the socketClient as that operation that we ran against the server. This one is called receive. Pretty simple right? Then I am simply using the ASCII encoding to convert the binary data back into the string. Test it out! Look at that... it's magic. There is still a matter that we must discuss however, and it's very important. You see we created the byte array by allocating only 13 bytes of memory. This is not nearly sufficient for almost any application that we will write. So why did I do this? Why didn't I allocate larger? I could have allocated larger. That is not the issue. The issue lies with the read/recieve operation. You see much like the write operation, the read asks me to specify a byte array to read data into, an index to start reading from, and a size, or in this case length to read. I told it to consume the whole array. I knew the message "Hello, World!" was 13 bytes. Lets Experiment. Try setting the array size to 10, then run the application. Runs as expected, the client pulls only 10 of the 13 bytes and both ready to terminate. Now try to set it to 100. Then Run it. Does it run as expected? No, not exactly. I think what you will find is that you get the message, but you're getting a lot of extra 'nothings'. In this example, perhaps it's not much of a problem. As your programs get more complex, especially once you get into asynchronous sockets, this becomes a real issue. In some circumstances, your application could deadlock waiting for more data to be written to the buffer before ending the receive operation. Ok, I think we can leave this at that for now. A lot of ground has been covered in the last two posts. Maybe a good time for you to experiment and become comfortable with some of the concepts. Also, if you can try changing things, and seeing if you can break it, that would be another great experience. However, for those who want more... I also said I would get into how to enable to server to accept more clients. Probably the easiest way to do this with what we have is to use a loop that keeps executing the Accept statement. And I think for at least the purposes of explaining how simple Blocking Sockets are, and some of their shortcomings, that is exactly what we will do. Let's do something rash. Lets create an infinite loop that accepts connections and sends our welcome message. Yes, I realize this will cause unreachable code, and I'm fine with that for now. This is just to illustrate a point, so bear with me...
static void Main(string[] args) {
IPEndPoint epLocal = new IPEndPoint(IPAddress.Any, 13001);

Socket socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socketServer.Bind(epLocal);
socketServer.Listen(4);

Socket socketClient;
for (; ; ) {
socketClient = socketServer.Accept();
byte[] bytSend = System.Text.ASCIIEncoding.ASCII.GetBytes("Hello, World!");
socketClient.Send(bytSend, 0, bytSend.Length, SocketFlags.None);
}

Console.WriteLine("Press to terminate");
Console.ReadLine();

socketServer.Close();
}


OK, we can see that the client that connects get's its message, and is given the option to hit enter and then terminate. But the server, still nothing. Lets try to connect to it with telnet now, without restarting the server. It works.. so how do we stop the server? I think that's a good question. I mean yes, we could just terminate the process, but how about something a little more solid/proper? I'm going to do something now that I didn't plan on doing right away, because I think it would be highly beneficial, again this will illustrate the strengths and weaknesses of Blocking Sockets vs. Asynchronous Sockets. Are you familiar with Asynchronous Programming? If you said no, don't fret. If you have programmed in almost any visual environment, you're more than likely more familiar with Asynchronous Programming than you even realize. Asynchronous Programming allows us to perform certain tasks. while our main thread continues executing. Or maybe more appropriately, it allows us to wait for certain things to happen while our main thread continues executing. The main thread would get interrupted when this task completes. If you picture in your mind, programming the result of clicking a button, you're in the right mindset, on how the code will look. If we replaced the Accept call with a BeginAccept() call, that would kick off an asynchronous Accept. This means that rather than wait for the connection on the current main thread, the server will wait for the connection, and let us know when a connection has been made. This means that the server will walk right over BeginAccept Call, and then display the message that states we can press the Enter Key and the server will terminate. (of course we no longer need the loop). Once a connection is made, our callback gets fired. This is a method we designate at the time we call BeginAccept(). That method being fired is our notification that the Accept operation has been completed. If we call EndAccept passing in our AsyncResult, we get our client socket just the same as though we had called Accept() straight up. And there is no reason why we cannot call BeginAccept() again. So clear out that Accept loop altogether. And create a new Method. This method will be used as a callback when the Accept operation completes.
static void OnAcceptComplete(IAsyncResult result) {
Socket socketServer = (Socket)result.AsyncState;
Socket socketClient = socketServer.EndAccept(result);
byte[] bytSend = System.Text.ASCIIEncoding.ASCII.GetBytes("Hello, World!");
socketClient.Send(bytSend, 0, bytSend.Length, SocketFlags.None);

socketServer.BeginAccept(OnAcceptComplete, socketServer);

return;
}


This is a special method signature. returning nothing, and taking only an IAsyncResult parameter, this is the signature that pretty well all Asynchronous Methods will expect as a callback. The first thing we are doing is extracting the server socket, which is expected to be the Asynchronous state. (I will explain that in a few minutes) Next, we are going to call EndAccept on the server socket. This returns the client socket just like calling Accept Directly, as well as cleaning up the Async Operation. Then we send the "Hello, World!" message the same way we did previously. And we attempt to wait for another connection asynchronously. Now in order to tie this altogether, we need to kick off the AsyncAccept pattern in the first place. This can be accomplished by replacing the original Accept with a Begin Accept. Make your server application look like this.
static void Main(string[] args) {
IPEndPoint epLocal = new IPEndPoint(IPAddress.Any, 13001);

Socket socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socketServer.Bind(epLocal);
socketServer.Listen(4);

socketServer.BeginAccept(OnAcceptComplete, socketServer);

Console.WriteLine("Press to terminate");
Console.ReadLine();

socketServer.Close();
}

static void OnAcceptComplete(IAsyncResult result) {
Socket socketServer = (Socket)result.AsyncState;
Socket socketClient = socketServer.EndAccept(result);
byte[] bytSend = System.Text.ASCIIEncoding.ASCII.GetBytes("Hello, World!");
socketClient.Send(bytSend, 0, bytSend.Length, SocketFlags.None);

socketServer.BeginAccept(OnAcceptComplete, socketServer);
return;
}


Try and run the solution again now. You should see everything executes as expected. The client gets its welcome message, and a chance to terminate. So does the server. But if you don't close the server, you can start connecting telnet clients to it, notice they work as expected as well? This is really only one advantage to Asynchronous sockets. I will leave you on that note, because I know a lot of these concepts must be hard to swallow all at once. So please, if you have any questions, or I'm not clear enough on something, let me know, and I'll try and straighten you out. I suspect that will be the case, because my two year old is helping me out right now.. =) Next lesson, I will try not to introduce much more, but rather re-enforce some of these concepts. After all, if you can grasp all of this so far in just two lessons, you're doing way better than I did. I figure once we get some of these concepts down, I'll remove all the blocking stuff, and show you pure Asynchronous sockets, and some of the patterns that I use. I'd also like to show you some of the .NET features that actually make sockets convenient.

Thursday, November 6, 2008

"Traditional Sockets" in .NET -- Part 1

The title may be a little misleading, because when I say "traditional sockets", I don't necessarily mean I stick to any sort of convention... A couple of days ago, a co-worker of mine and I were talking; and sockets came up as an alternative to newer possibly more mainstream .NET technologies. I was asked to explain and maybe even provide a sample to pose as a starting point to become acquainted with sockets and network programming.

I did, and I felt that there may be some poor sap willing to tread through this entry and possibly learn something. Though, I'll warn you, there are at least 100 other blog entries that will explain this more properly.

Still here?... OK, read on...

I have come to realize that I can write for ages on the topic, and While I would love to show some of the more advanced features, I'm just going to loose my audience. So I'm going to start off really slow here. If you have some experience on the subject, please provide feedback. I love discussing these things. I'll progressively move into some more interesting parts of the framework I have combined with sockets to make for some really interesting applications.

Is it alright for me to assume that for the most part, readers are at least at an intermediate level with C#? I don't really want to explain standard convention, or syntax. Though I will gladly respond to anyone who has any question, or doesn't understand something.

So let's start this tutorial series, by creating a simple Hello, World! server. One that will accept a connection from a client, print the Hello, World! message and disconnect that client. For starters, let's just do a simple blocking server. Once the client has been disconnected, we will let main() return, and the server application will exit. It might not be practical in the real world, but who cares? lets have some fun! I'll get to the good stuff... but you need a foundation first.

For starters, create a Console Application in Visual Studio. I'm using 2008 Professional, but I believe this code will work for 2003 - 2008. Someone correct me if I'm wrong, I don't have the ambition to go through and run tests for each environment.

So create your Console application and start editing the Program.cs file.

Make sure your importing out of the networking namespace.


using System;
using System.Net;
using System.Net.Sockets;

Now move down to the static void Main(string[] args) method.

Let's talk a moment about what the server is going to have to do to accept a connection.

First, we have to realize that the server is going to have to lay down the law in terms of how it is going to communicate. We can explore your options in more detail down the road, or possibly in a few more tutorial lessons, but for now, lets just say that you will almost always be using something like this. Especially while you are learning.


Socket socketServer = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);

There really isn't a difference between a client and a server socket. At least when we construct it. However you will want to ensure that a client socket is created with the same rules as the server socket. This specific configuration will work over the internet, maintains a constant connection and ensures that data that is transmitted will reach it's destination, and the destination will receive the data in the same order that you sent it. It's very reliable, and very similar to most internet applications that you use, so the performance hit will not likely be something you are aware of. Again, we can get more into this later. Let's move on.

So what is the difference between a client and a server configuration?

A server "accepts" connections, and a client generally "connects" to a server. This is a great terminology, as this is the same terminology you will see using the socket framework.

We will get into how to set up a client later, probably next lesson.

If you were to look at the socketServer members (probably by typing socketServer. and looking through the list of members using intellisense) you will notice an Accept method. What do you want to bet that this is the method that is used to accept connections.

Lets look at our main method now,

static void Main(string[] args)
{
Socket socketServer = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
Socket socketClient = socketServer.Accept();
}

I hope your following along, this is all technically correct, however incomplete. We have a socket and defined how it behaves. We are also attempting to accept a client connection. But we really havent given the socket context.
Think back to almost any network program you have used. Generally when we attempt to connect to a service of any sort with a client, we must specify either a hostname or IP address, as well as a port number.
If you're new to this it's concievable to think that a server running on this machine will be available to any client that can see it, by it's IP address and / or Host name, as long as that host name will resolve into an IP address, and you're probably right. But what if your machine had more than one Network interface card. One facing the internet, and the other facing a LAN. What if you didn't want your server to be accessable by the WAN. No.. lets take this a step further, the two network cards are two separate network interfaces. Each technically participates in a separate network. And this really says nothing in the way of which port the server is serving on.
Did you know that only one server can exist on any one end point? An end point in this context is an address and a port number. Any one Address of this type can have up to 65535 ports open.

Ok enough theory, we can get into the specifics later. And yes, we do have a way of just opening the server on all interfaces at the same time.
Before we can accept connections to a socket, the socket must be bound to an end point. If you attempted to run that code right now, you would get an exception indicating something similar.
The good news is that it is very simple to both define an bind to an end point. You just need to be certain you arent attempting to bind to an end point that has already been bound to.

Try this.


IPEndPoint epLocal = new IPEndPoint(IPAddress.Any, 13001);

This defines an edpoint using a constant that specifies any interface on the machine, and port number 13001. I doubt you have any service using port 13001, but if you do, just change it to something differnet. Just keep it in the higher numbers and don't exceed 65535. (most well known and used port numbers are lower values). We can later talk about that, but if you googled well known services or something similar, you'd get a list of common port numbers.

By the way, you defined an end point, you you havent used it yet. technically, you bind with socketServer.Bind(epLocal);


static void Main(string[] args)
{
IPEndPoint epLocal = new IPEndPoint(IPAddress.Any, 13001);

Socket socketServer = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
socketServer.Bind(epLocal);
socketServer.Listen(4);
Socket socketClient = socketServer.Accept();

socketClient.Close();
socketServer.Close();
}
I also stuck in a Listen(4) in there. If you weren't aware, this allows me to specify how many clients can remain in the connect Queue to be accepted. This is NOT a maximum number of connections, I'm afraid you would have to code something like that yourself. This is useful because it would automatically turn away clients if the server was overloaded with clients attempting to connect. We will get into this later too. Don't worry about it now...

This would work now. You can try it, but you won't see much yet. If you were to run this, a console application will start, with a black screen, and appear to do nothing. You might even get a message from whatever firewall software you are using, asking if you want to block the server or not. I added the Close() statements, just to remind us that when we no longer need these resources, we should be releasing them.

If you were to open a windows console, and type something like telnet 127.0.0.1 13001, you would see your server window close, and you would probably not see anything in the telnet session, because the server hasn't sent any data.

Now even though you cannot see an awful lot happening, there is a lot more happening than meets the eye. The Accept() statement is very powerful, and must be used with consideration. Accept() is considered a blocking statement. When you call it, the application will wait until a client connects. This particular use of sockets is called "Blocking Sockets".

Blocking Sockets are a great place to start, because you can write very simple networked applications. You don't need to worry about a lot going on. Once we bring this tutorial into more real world examples, I'll introduce Asynchronous Sockets. Don't worry about this for now.

So let's complete our server. Why don't we send a Hello, World! to the client.

After the Accept() call, why not add something like this.

byte[] bytSend =
System.Text.ASCIIEncoding.ASCII.GetBytes("Hello, World!");
socketClient.Send(bytSend, 0, bytSend.Length, SocketFlags.None);

If this looks confusing, don't let it. I have simply taken the binary for the string Hello, World! represented as ASCII text, and set it into a byte array. Sockets transmit data in binary form.

The next statement simply says send data out of the bytSend array, start at index 0, and transmit the the full length of the array. The third argument is actually size, and because each byte is 1 byte in size, it naturally translates to number of indexes to transmit. Moving along..
We are not going to get into SocketFlags right now.

your program should look like this now.


static void Main(string[] args)
{
IPEndPoint epLocal = new IPEndPoint(IPAddress.Any, 13005);

Socket socketServer = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
socketServer.Bind(epLocal);
socketServer.Listen(4);
Socket socketClient = socketServer.Accept();

byte[] bytSend =
System.Text.ASCIIEncoding.ASCII.GetBytes("Hello, World!");
socketClient.Send(bytSend, 0, bytSend.Length, SocketFlags.None);

socketClient.Close();
socketServer.Close();
}

Go ahead, give it a try. Execute the code and then connect with the telnet client.

The server terminates, but the client now get's it's Greeting.

Congratulations, You've just written your first server. It's a silly server that does not do anything really useful, but a server none the less. Tomorrow I will try and find some time to elaborate on something more practical.

Next tutorial, I will focus on the following.
  • Creating a client application that connects to this server
  • And we will give the server the ability to wait for additional clients after the first, so it does not terminate after sending the message to the client.
  • I might move into two way communication as well, It really depends on how the client aspect looks on paper. I don't want to overwhelm anyone.
Now, that siad, if anyone needs any more detail on anything I've talked about, or has any requests on... well.. anything that I may know, please ask away.

I apologize for the fact that this is moving slow, I have no idea how on the ball you guys are, I just don't want to leave anyone behind.

Thanks for reading!

Tuesday, October 28, 2008

Can the internet really be profitable?

Can the Internet really be profitable?

I know that's a funny question. All kinds of people have made their millions at least with the assistance with the internet. But I mean more in a realistic sense, a situation where (money.earned == (effort.spent/time.spent)). That, and not everyone has the heart to scam money out of those with better constitutions. By this I mean MLM scams etc.

I've been using the internet for years. At least since mid 90's. In the last week, I've earned more money online than I ever thought possible. It's true. On this blog alone, though advertising, I have raised almost 10 dollars. And by completing some of those web perspectives surveys, I've raised yet another almost 10 dollars. This is crazy... just crazy..

Now to be fair, I think I'm receiving payment for surveys completed months ago... It really begs the initial question, is it worth the time and effort?

If a survey takes I dunno, 30 - 40 minutes to complete, and you have to wait for at least a month for payment, there isn't much point in taking the survey at all. Not unless it was your spare time.

Now that being said, How much is your spare time worth? I'm a professional software developer, and while I won't get into exactly how much I make, I will tell you that the difference in value is outstanding. If I work outside my normal work hour's I'd consider that eating into my spare time. Yet at the least, I bill my regular hourly rate, or take time off to make up for it.

This blog post is going to take something like 20 minutes of my time; because I don't really care if I look a little rough on the edges. I'm not sure how attractive the advertising will look from it, and subsequently how likely people are to be attracted to any of it, but if I were to look at the statistics, this post could potentially generate 4 dollars worth of income over a few days.

So this is a lot more effective than completing surveys. But still, is it worth my time? Does the fact that I'm doing this out of interest make a difference? Maybe that should fit into the initial equation somewhere....

(money.earned == (effort.spent/time.spent)) + satisfaction ???

or

I enjoy it, so.. (satisfaction + money.earned) == super bonus

obviously I'm no mathematician.

Has anyone out there actually found practical things, that you don't hate doing, to be profitable on the internet? But let's just rule out selling all your belongings on E bay right now.

I'm all for hearing stories on various ventures. However, I'm more interested in hearing if the internet is actually profitable in this way, not to be sold in some business opportunity.

Thursday, October 23, 2008

An intrusion a firewall wont protect you from...

So I sit down here after getting the kiddos to bed. And I read my email. I get these newsletters from a few places, that keep me somewhat up to date in the technical worldly happenings. One story struck me as funny, and I just had to share; because this story really made me think.

A few years back I was awfully concerned to do my online banking over a wireless network connection, especially the first few times I used a wireless network connection. Even now with encryption and security features, you can't help but think that it would be a better idea to transmit sensitive data over a wire, and not through the air right?

Apparently one doesn't even need a network connection to be snooped on. Apparently a couple of guys from a Swiss research laboratory have discovered a way to remotely key log directly from the keyboard. No, I'm not talking about a wireless keyboard either. Apparently they are decoding electromagnetic pulses up to 20 meters away, and through walls. And apparently USB, PS/2 and Laptop keyboards are all affected. I wonder if wireless keyboards are affected...

Tin Foil hats anyone?

Oh, http://news.cnet.com/8301-1009_3-10072967-83.html
There is a link in there you can follow with video footage of these attacks.

Wednesday, October 22, 2008

Hello, World!

So, I'm a 26 year old Canadian developer. I've been practically raised online, and I've never had a blog. Of course I think I missed a few other big things as well. As a matter of fact, do you people still read these things?

Followers