Sunday 12 February 2012

The .NET Sockets – The Investigation (1)!

The Windows Socket programming has never been the favourite subject of many developers. Looking at the resources I can find, my guess is it is considered C/C++ topic.

Before going too deep into sockets, we should clarify what an endpoint is. Now an endpoint in the context of socket programming is an address and a port number. The combination of an address (e.g. 192.168.1.1) and a port (e.g. 8992) provides us a unique endpoint which a client can use for communication (e.g. 192.168.1.1:8992). 

Once the communication channel has been established between two endpoints each participant can send and receive data.

 The data received from a socket can be read synchronously or asynchronously. A simple search will return many hundreds of articles written about this subject. 

My goal of this post is to start very simply by creating a socket and build on it. We will then create a server followed by a client.

So let us create a socket. When creating “stuff” like sockets I tend to use a factory (pattern).

[Most importantly before writing any code, consider whether the code is testable. I am not going to use any IOC frameworks here, but make sure you consider using C# “interfaces” at least.]
Consider the following contract.

using System.Net.Sockets;
namespace Common
{
/// <summary>
/// Interface for creating a <see cref="System.Net.Sockets.Socket"/>.
/// </summary>
public interface ISocketFactory
{
  Socket Create();
 }
}

Now you would argue that since I am using a factory to create a socket, I could also use an “ISocket”. I considered that, but purpose of this post is to educate about the use of sockets. 
Let us implement this interface.

using System.Net.Sockets;
namespace Common
{
/// This class creates a socket.
public class SocketFactory : ISocketFactory{
/// Creates a TCP/IP socket and sets its  to close immediately. 
public Socket Create(){
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp
        {
                                 LingerState = new LingerOption(false, 0)
                             };
            socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            return socket;
}
}
}

We have created a “TCP/IP” socket. One most important thing to remember is that there is already a “TCPClient” class which wraps a socket designed specifically for “TCP/IP” communication. I would prefer to use the above technique rather than the built-in “TCPClient”/related classes. Alternatively you can use “.NET Reflector” to check what is happening under the hood of “TCPClient” class.

The “AddressFamily” defines addressing scheme used by the socket. Since we are using “TCP/IP” socket, we should use “AddressFamily.InterNetwork”. The “SocketType” defines the type of socket (obviously...). We must use “Stream” here in order to adhere to “TCP/IP” standard.  And finally the protocol type, which in this case is “TCP”.

The next most important property you should be concerned is “Linger”. The idea behind setting the “Linger” option is to ensure that the socket is closed as soon as the “Socket.Close” method is called and the port is released.  Closing a socket gracefully is a subject on its own and you should read this entry - http://msdn.microsoft.com/en-us/library/windows/desktop/ms738547(v=vs.85).aspx. Make sure you visit this link as well - http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4468997.

Ok, that will do for the moment. Let us visit the Server code next.

References:

C# Network Programming – Richard Blum

MSDN

No comments:

Post a Comment