Brief Introduction to Free SSL/TLS Enabled Non-blocking Socket Library udaparts 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 dont against its original developer. The article mainly focuses
on pointing out a set of key features with short comments. Wish you like it. First of all, the library is free to use for
whatever purposes without any warranty. The only requirement is that you cant
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.
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) {
txtData.Text = "Host Name = "
+ bstrHostName + "; Alias = " +
bstrAlias + "; IP Addr = " +
bstrIPAddr;
else
txtData.Text = m_ClientSocket.ErrorMsg; }
|