Simple Network Programming





5.00/5 (4 votes)
A simple way to do network programming
Introduction
When I first started programming approximately 5 years ago, I was dreaming big. I wanted to make a chat system from scratch with no issues that was fast, reliable, and lightweight.
However, most ambitious projects for new programmers get shot down real fast and this was no different. I searched and struggled to find a decent system or decent code that would allow me to do some simple communication with two clients with a centralized server. Apparently, that was rather difficult for me to find (I didn't get good with Google until a few years later) anything that would do exactly what I wanted.
A few years go by and I gathered more skill and I decided, "Hey, I should write that chat system". So I did just that. It stunk, but I learned quite a few things. RattleSnake
is an example of the things I learned.
Background
I wanted a flexible system that would take anything I gave it, and produce what I wanted. That sounds really stupid sounding, but bear with me. I wanted to be able to serialize structures, or send custom coded byte arrays without having to change my methods of sending. RattleSnake
can do just that.
This started as a pet project and has evolved into something massive. RattleSnake
can handle just about whatever you actually want, from Client-Server connections, to even handling UPnP.
RattleSnake
has 4 major namespaces:
RattleSnake.Client
RattleSnake.Client.Client
RattleSnake.Client.TcpClientEx
RattleSnake.Server
RattleSnake.Server.Server
RattleSnake.Server.TcpListenerEx
RattleSnake.Security
RattleSnake.Security.WhirlpoolManaged
- Please note that this class is not of my creation. I just converted it from C#. The original license and notices with the class are still in place to credit the original authors.
RattleSnake.Security.MersenneTwister
- As with
WhirlpoolManaged
, I did not create this. I just converted it from C#. The original license and notices with the class are still in place to credit the original authors.
- As with
RattleSnake.Security.Encryption
RattleSnake.UPnP
It's quite clear what each namespace actually contains and what it does.
I had to do a few cases of Inheritance, such as inheriting the TcpClient
& TcpListener
to provide future functionality (the MyBase.Active()
property for example) as I update this project. For now, though, RattleSnake
is relatively complete minus a few new features I want to put in.
Using the Code
It's extremely simple to use RattleSnake
's Client, Server, UPnP
, and Security features. The Client and Server are completely event driven, making it pretty simple to understand.
Here's a quick example of using the Client:
' This is for the Client.
Dim _rsc As New RattleSnake.Client.RattleSnakeClient()
' Now perform a connection
_rsc.Connect("127.0.0.1", 6110)
That is all you need to do to perform a connection. But, how do we keep track of when the client connects? What about receiving data, or a disconnection, or even an exception? The RattleSnakeClient
class has events to handle all of that:
Public Event ConnectionEstablished(ByVal sender As Object, _
ByVal e As EventArgs.RattleSnakeClientConnectionEstablishedEventArgs)
This event will fire when a connection is established. The EventArgs
passed contains the following properties:
IP
- Returns the IP address that the client is connected to (as aString
).Port
- Returns the Port number that the client is connected to (as aPort
).
Public Event DataReceived(ByVal sender As Object, _
ByVal e As EventArgs.RattleSnakeClientDataReceivedEventArgs)
This event will fire when Data
comes through the connection. The EventArgs
passed contains the following properties:
Data
- Return a byte array containing all the data that was received.Object
- Attempts to return an object that represents theData
received by means of serialization. If the serialization fails, it returns aNew Object
.
Public Event Exception(ByVal sender As Object, _
ByVal e As EventArgs.RattleSnakeClientExceptionEventArgs)
This event will fire when the RattleSnakeClient
throws an Exception. The EventArgs
passed contains the following properties:
Exception
- Returns the exception that was thrown.
These events are easy, straightforward, and keep RattleSnake
running smoothly.
Sending data is also extremely simple with RattleSnake
:
'Define some random data in a Byte Array; filled with junk data or what not.
Dim _data As new Byte(255)
'Now send it with RattleSnake
_rsc.BeginSend(_data)
It is that easy to send data with RattleSnake
. It is also possible to simply pass the .BeginSend()
method with an Object
that is Serializable and have it be sent as well; RattleSnake
makes use of that internally.
Disconnection is a breeze as well:
'Disconnect.
_rsc.Disconnect(True)
In RattleSnake
, unless it's really important, .Disconnect()
will always take a True
. The True
tells RattleSnake
to notify the other side that a disconnection is happening. I do this just to make sure that there are no Exceptions raised on the other end that could otherwise be avoided.
Now, a quick overview on the UPnP
class in RattleSnake
. The UPnP
class allows for the quick and easy addition (or removal) of port mappings on UPnP
enabled devices. This is a list of the methods, properties, and enumerations of the UPnP
class:
- Protocol
- TCP
- UDP
Add()
Remove()
Exists()
LocalIP()
Print()
Dispose()
Each method has XML style comments, so I won't go into much details here, but it's pretty easy to add a port mapping to a UPnP
enabled device:
Using rs = New RattleSnake.UPnP.UPnP
rs.Add(RattleSnake.UPnP.UPnP.LocalIP(), 100,
RattleSnake.UPnP.UPnP.Protocol.TCP, "Description")
End Using
That is all it takes to add a port mapping to a UPnP
enabled device. The code adds a mapping to the local IP address, on port 100, with the TCP protocol and a description of "Description
". Removing is pretty simple as well:
Using rs = New RattleSnake.UPnP.UPnP
rs.Remove(100, RattleSnake.UPnP.UPnP.Protocol.TCP)
End Using
The port that was just added earlier has now been removed. The Add()
and Remove()
routines internally call Exists()
so, as a programmer, it's not required to do it as well (However, the class will throw an ArgumentException()
).
RattleSnake
, as a whole, should not be riddled with bugs. It has gone through multiple field tests without many errors at all, but if any bugs should pop up, I will try my best to fix them as quickly as possible.
Points of Interest
I should note that RattleSnake
has seen its fair share of rewrites. As of 12/5/2011, this is the third rewrite of RattleSnake
to provide cleaner and more efficient code. UPnP
is a recent addition to RattleSnake
and one that took me a bit of research to figure out how to easily do in Windows. I use the term 'easily' rather loosely because it's relatively simple but takes a bit of figuring out to make it work (such as it only works in I believe .NET 3.5 and above as the required Interface isn't exposed in .NET 2.0).
History
- 12/5/2011 - Initial release