Home Products Consulting Download Registration Support Events

Home
Up

Brief Introduction to Free SSL/TLS Enabled Non-blocking Socket Library

    udaparts
    support@udaparts.com
    08/03/2007

    Sample codes and dlls for C++, eVC++, C# and VB.NET

    Remote communication is one of the most important parts for any world-class applications. TCP/IP socket is definitely the most successful communication protocol among all of available communication methods. It is matured, well approved and testified by many outstanding commercial applications like Firefox, Internet explorer, Apache, Internet information server, Oracle database, and so on.

    However, programming on TCP/IP socket level is not welcome to new programmers mainly because of its complexity. TCP/IP socket has a set of synchronous API functions and we like synchronous calls, but the nature of TCP/IP socket is its data communication asynchrony. Without getting used to asynchronous communication, it is impossible to fully take advantage of socket communication power.

    This short article introduces you a free and simple but powerful SSL/TLS enabled TCP/IP non-blocking socket library for window development with a set of samples for C++, C# and VB.NET. You can use the library for whatever purposes as long as you don’t against its original developer. The article mainly focuses on pointing out a set of key features with short comments. Wish you like it.

      1.    Free for all of purposes

First of all, the library is free to use for whatever purposes without any warranty. The only requirement is that you can’t do anything to against original creator, but your questions and suggestions are truly welcome, which push us to keep on improving it a little by a little.

When you use this library in either desktop computer or a device (pocket pc or smart phone) as attached in the above zip file, you need to register and reference usocket.dll for your development environment because it is a standard COM library.

2.   100% non-blocking communication

The library fully takes advantage of non-blocking socket communication power. Blocking socket communication is simpler and easier to get started, but it lacks power and makes code reusability much more difficult later. Contrarily, non-blocking socket is complex and difficult to get started but it offers much more power with much more simplicity for code reuse.

Many calls within an application are involved in slow I/O communication or long duration with a remote machine. Typically, you are forced to start a worker thread and execute these calls from the worker thread. It requires you a considerable amount of codes and efforts to solve a set of thread-related problems such as race condition, data synchronization, dead lock and data communication among threads. Contrarily, if you use this library, usually you are not required to create a worker thread for slow I/O communication and long duration calls at all, which leads to code simplicity and better code maintainability.

The second huge advantage of non-blocking socket communication is performance and scalability. With non-blocking socket communication, requests and returning results can be easily batched either automatically or on purpose (manually) for reduction of wasting limited Internet bandwidth and both client and server CPU resources. You can use worker thread plus blocking communication approach to improve performance and scalability, but its improvement is actually limited.

The third huge advantage of TCP/IP communication is that all of network devices on communication path can work in parallel by nature if multiple requests are queued for one single connection. Assuming we have four requests to send out to be processed, at one time the four requests can be distributed on data movement path like this: one at client CPU, one at physical transportation level, one at switch or hub, and one at server CPU. Similarly, four returning results could be like this: one at server CPU, one at physical transportation level, one at switch or hub, and one at client CPU. As you can see, data movements can happen in parallel. This feature makes your application faster, more scalable and a little more intelligent. If you use blocking socket communication, it is impossible to ensure all of networks devices work concurrently for one connection so that data communication is less performant and less intelligent no matter how you use a worker thread.

The above three key advantages makes non-blocking socket level communication very powerful in comparison to blocking socket level communication. As an example, you can see these huge advantages at this site. You can be assured that you NEVER find a .NET remoting or WCF application can match our SocketPro in performance and scalability no matter how much effort and money you put on .NET remoting and WCF because these frameworks are created on blocking socket communication.

By nature, non-blocking socket communication does not freeze client window graphical user interfaces.

3.   A set of socket communication events

The COM object provides a set of socket communication events. The key ones are OnSocketConnected, OnSocketClosed, OnDataAvailable and OnOtherMessage. You can rely on these callbacks to get socket communication events immediately.

    Once a connection is established, the event OnSocketConnected arrives as shown in the below code snippet:

m_ClientSocket.OnSocketConnected += new _IUSocketEvent_OnSocketConnectedEventHandler(m_ClientSocket_OnSocketConnected); //subscribe for event

……

void m_ClientSocket_OnSocketConnected(int hSocket, int lError)

                {

                                if (lError == 0) //no error

                                                btnSend.Enabled = true;

                }

    The second key event is OnSocketClosed.

m_ClientSocket.OnSocketClosed += new _IUSocketEvent_OnSocketClosedEventHandler(m_ClientSocket_OnSocketClosed);

……

 

void m_ClientSocket_OnSocketClosed(int hSocket, int lError)

                {

                                btnSend.Enabled = false;

                                if (lError != 0) //has an error

                                                txtData.Text = m_ClientSocket.ErrorMsg;

                }

    Unlike .NET remoting and WCF communication frameworks, this library enables you to catch the disconnection event immediately without use of try and catch.

    Once a remote host sends a data, the event OnDataAvailable happens. Inside the callback, you can use the below code to retrieve the returned data in byte.

m_ClientSocket.OnDataAvailable += new _IUSocketEvent_OnDataAvailableEventHandler(m_ClientSocket_OnDataAvailable); //subscribe for event

 

……

 

void m_ClientSocket_OnDataAvailable(int hSocket, int lBytes, int lError)

                {

                                byte[] bytes = (byte[])m_ClientSocket.Recv();

                                if (bytes != null && bytes.Length > 0)

                                {

                                                bytes = Encoding.Convert(Encoding.UTF8, Encoding.Unicode, bytes);

                                                string str = Encoding.Unicode.GetString(bytes);

                                                txtData.Text += str;

                                }

                }

    At this time, it is a common practice to use industrial standard protocol SSL/TLS to secure data communication between two computers. The library exposes SSL/TLS handshake events. Here is code snippet for demonstration of SSL/TLS handshake events. 

m_ClientSocket.OnOtherMessage += new _IUSocketEvent_OnOtherMessageEventHandler(m_ClientSocket_OnOtherMessage); //subscribe for event

……

                                               

void m_ClientSocket_OnOtherMessage(int hSocket, int nMsg, int wParam, int lParam)

                {

                                if (nMsg == (int)USOCKETLib.tagClientMessage.msgSSLEvent)

                                {

                                                switch ((USOCKETLib.tagSSLEvent)wParam)

                                                {

                                                case USOCKETLib.tagSSLEvent.ssleDoSSLConnect:

                                                                txtData.Text = "SSL Event: " + "Doing SSL/TLS Connecting";

                                                                break;

                                                case USOCKETLib.tagSSLEvent.ssleHandshakeDone:

                                                                txtData.Text = "SSL Event: " + "SSL/TLS Handshake Done";

                                                                {

                                                                                int nErrorCode = 0;

                                                                                USOCKETLib.IUCert UCert = (USOCKETLib.IUCert)m_ClientSocket.PeerCertificate;

                                                                                UCert.VerifyLocation = txtHost.Text; //subject

                                                                                string str = UCert.Verify(out nErrorCode); //verify certificates chain here

                                                                                if (nErrorCode != 0)

                                                                                {

                                                                                                txtData.Text = str;

                                                                                }

                                                                }

                                                                break;

                                                case USOCKETLib.tagSSLEvent.ssleHandshakeExit:

                                                                txtData.Text = "SSL Event: " + "SSL/TLS Handshake Exit";

                                                                break;

                                                case USOCKETLib.tagSSLEvent.ssleHandshakeLoop:

                                                                txtData.Text = "SSL Event: " + "SSL/TLS Handshaking ......";

                                                                break;

                                                case USOCKETLib.tagSSLEvent.ssleHandshakeStarted:

                                                                txtData.Text = "SSL Event: " + "Starting SSL/TLS Handshake";

                                                                break;

                                                case USOCKETLib.tagSSLEvent.ssleReadAlert:

                                                                txtData.Text = "SSL Event: " + "SSL/TLS Read Alert";

                                                                break;

                                                case USOCKETLib.tagSSLEvent.ssleWriteAlert:

                                                                txtData.Text = "SSL Event: " + "SSL/TLS Write Alert";

                                                                break;

                                                default:

                                                                txtData.Text = "SSL Event: " + "SSL/TLS Unknown Event";

                                                                break;

                                                }

                                }

                }

    4.   A free and complete solution for remote accessing any server using TCP/IP socket level programming.

The library implements the following features plus a few others.

  1. Connection timeout – By default, connection timeout is 30 seconds. If you want to change this setting, you can alter it before calling the method Connect.
           
  2. Lots of events – In addition to the above four key events, you can see the other events by use of OLE/COM object viewer.
           
  3. SSL/TLS fully supported – As shown in this sample, the library fully supports SSL/TLS. To use SSL/TLS, All you need to do is to set the property EncryptionMethod before establishing a connection to a remote host as shown in the below.

private void btnConnect_Click(object sender, EventArgs e)

                {

                                int nPort;

                                try

                                {

                                                nPort = int.Parse(txtPort.Text);

                                 }

                                 catch (Exception err)

                                {

                                                MessageBox.Show(err.Message);

                                                return;

                                 }

 

                                if (txtHost.Text.Length == 0)

                                {

                                                MessageBox.Show("Remote host not specified!");

                                                return;

                                 }

                                if(chkSSL.Checked)

                                                m_ClientSocket.EncryptionMethod = (short)USOCKETLib.tagEncryptionMethod.MSTLSv1;

                                 else

                                                m_ClientSocket.EncryptionMethod = (short)USOCKETLib.tagEncryptionMethod.NoEncryption;

         

                                m_ClientSocket.UseBaseSocketOnly = true; //use basic socket function only

                                m_ClientSocket.Connect(txtHost.Text, nPort, false, 0, 0, 0, 0);

}

Once SSL/TLS handshake is done, you can retrieve a certificate transferred from the remote host. You can verify the certificate against trusted certificates and its relationships (chains) stored in your local machine as shown in the above section.

d.      Host resolving either synchronously or asynchronously – As shown in the attached sample, you can easily resolve remote host information asynchronously. In fact, it supports synchronously resolving host information too.

m_ClientSocket.OnGetHostByName += new _IUSocketEvent_OnGetHostByNameEventHandler(m_ClientSocket_OnGetHostByName); //subscribe for event

……
                               

void m_ClientSocket_OnGetHostByName(int hHandle, string bstrHostName, string bstrAlias, string bstrIPAddr, int lError)

{
                                 if (lError == 0)

                                txtData.Text = "Host Name = " + bstrHostName + "; Alias = " + bstrAlias + "; IP Addr = " + bstrIPAddr;

                                 else

                                                txtData.Text = m_ClientSocket.ErrorMsg;

}

       

  1. GetInterfaceAttributes – You can use this method to query the underlying network card information associated with a socket connection.
           

  2. An ATL based COM library for both single and free threaded apartments – The library is written from C++/ATL not only for high performance but also for the best reusability. You can reuse it from whatever a language as long as it understands MS COM technology.
           

  3. The library is thread-safe – The library is 100% thread safe. As an example, you can send requests from different threads at the same time without leading data overlapped. Similarly, you can retrieve data from different threads at the same time without causing any problem. If you use other libraries or frameworks, usually this may be a problem for you!
           

  4. Pocket PC and smart phone fully supported with a set of the same interfaces and methods – As shown in the above images, we provide you the same library for pocket pc and smart phone too. This may be an important feature for you. Actually, all of these libraries expose the same interfaces and methods as the library for desktop. Therefore, you can reuse desktop codes for these devices. As you may know, MS device socket library exposes a subset of functions for TCP/IP. To solve this problem, we fake a few functions for these devices so that you can easily port code from desktop to these devices.