Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
Available now!
Buy at Amazon US or
Buy at Amazon UK



Articles

» Windows API reference
» Webcam streaming in VB.NET
» Remoting with firewalls
» RSA from first principles
» Key & MouseLogger in .NET
» Networking Resource Kit for .NET
» Migrating VB6 Winsock to VB.NET
» Migrating C++ sockets to C#
» RFC Reference guide
» COM Reference guide
» WMI Reference guide
» SQL stored procedures
» TCP & UDP port reference
» NET Framework reference
» Ethernet Type codes
» MAC address assignments
» DLL entry point reference
» Boost SQL performance
» Free SMS UK
» Free SMS Ireland
» Free SMS South Africa
» Internet Explorer

Contact us

Migrating Visual Basic 6 Network code to Visual Basic .NET or C#

Network applications in VB6 was centred on the Winsock ActiveX control, which although simple to use had many drawbacks, which prevented it from use in high performance clients or servers. In .NET, these performance and scalability bottlenecks are negated by new features built into the .NET framework, including enhanced threading capabilities, and native socket handling.

This article show why you should not develop real-world network applications in VB6, instead, opt for C# or VB.NET. Complete .NET source code, and further explanation of the models referred in this article can be found in the book Network Programming in .NET (at Amazon UK) (at Amazon US)

The main differences between Visual Basic 6 networking code and .NET are as follows:

  • VB6 cannot handle multiple network requests simultaneously, .NET can.
  • The Winsock ActiveX control has a much larger memory footprint than a .NET socket. Therefore, VB6 network applications are more memory intensive.
  • .NET supports overlapped I/O, and can therefore read and write on the same socket simultaneously. VB6 does not support overlapped I/O, .NET supports overlapped I/O through asynchronous sockets.

It is for these reasons that it is imperative to avoid the temptation of using Visual Studio .NETís Visual Basic to VB.NET upgrade tool to migrate VB6 network code to VB.NET.

Using Winsock in VB.NET is like using a tractor engine in a Ferrari!, you will severely limit performance, reliability and scalability by doing so.

Concurrent network request handling

The root cause of VB6ís inability to correctly handle multiple network requests is that Visual Basic 6.0 had no native means of multithreading. VB 6 apartment threaded objects and programs are limited to execution in an STA (Single Threaded Apartment). This means that your exe or object can spin up as many threads as it wants, but only one thread in the apartment can execute at a time. Therefore there can be no concurrent execution of threads. Even if you use an out of process COM object you will only get two threads, one for your calling program and one for the COM exe, and each of them will be in an STA. Developers may have noticed that If one event fires, and goes into a DoEvents loop, i.e.

Do until (SomeVariable=true)
 Doevents
Loop

If another event fires during execution of a DoEvents Loop, then this will interrupt the loop, and the code execution will not return to the loop until the event completes. If the event attempts to call DoEvents itself, then the application will hang. Furthermore, a DoEvents loop uses 100% processor time.

VB.NET and C#, support an additional threading model, the free threading model, which forces an object to execute in an MTA (Multi Threaded Apartment), this threading model allows multiple concurrent threads of execution.

Memory leaks in network code

To demonstrate the memory footprint difference between VB6 and .NET, two functionally identical routines were written in VB6 and C#, to create 1000, 5000 and 10,000 sockets, and the impact on memory and time to instantiation were monitored.

In VB6, the following code was used:

Private Sub Form_Load()
 startTime = Timer
 For I = 1 To 10000
  Load Winsock1(I)
 Next
 MsgBox (Timer - startTime)
End Sub

And the results were:

3,276Kb for 1,000 sockets, after 0.46875 seconds

20,932Kb for 5,000 sockets, 2.53125 seconds.

42,984Kb for 10,000 sockets, after 5.34375 seconds

In C#, the following code was used to achieve the same effect:

private void Form1_Load(object sender, System.EventArgs e)
{
	DateTime dt = DateTime.Now;
	TimeSpan ts;
	Socket[] s = new Socket[10000];	
	ts = DateTime.Now - dt;
	MessageBox.Show("Elapsed:" + ts.Milliseconds);			
}

8Kb for 1,000 sockets.

36Kb for 5,000 sockets.

60Kb for 10,000 sockets.

The time elapsed in each case was zero. As it is plain to see, .NET is very significantly more efficient and memory sparing.

The standard means of handling multiple clients in a VB6 server was to create one Winsock object per client. Once a client closed the connection, the Winsock object could be freed. ActiveX components, such as WinSock have quite a substantial memory footprint, much more so than that of.NETís socket object, therefore if clients would be expected to maintain persistent connections, and one could expect numerous clients, then a system could be overwhelmed with demands to create more and more Winsock objects.

Furthermore, rapid instantiation and de-instantiation of Winsock objects is prone to memory leaks, such as KB 171996 ďWinsock Function Calls Generate Non-Paged Pool Memory LeakĒ

One means by which some developers have overcome memory leaks in vb6, was to initially create a set number of sockets, i.e. 10, and then allocate each one of the Winsocks to each new connecting client, once a client disconnected, the Winsock would not be de-allocated, but could be reused by other clients. This model would not support more than 10 concurrently connected clients, although it is quite analogous to the use of a Thread Pool in .NET.

The technique of using a Thread Pool to manage concurrent network connections in .NET is discussed in detail in the book, Network Programming in .NET (Buy at Amazon UK) (Buy at Amazon US)

Overlapped I/O

Overlapped I/O, (IO completion ports) are a high performance means of reading and writing simultaneously on the same socket. It is managed at system level, thus offering maximum performance. This technique has only been available since the advent of Winsock 2.0 in Windows NT, 2000, and XP.

Previously, it was only possible to implement I/O completion ports or Overlapped I/O through the use of the Windows API, and quite substantial code. Placing this level of network programming firmly in the realms of expert VC++ programmers, and would be non-trivial, if not impossible to develop in VB6.

.NETís Asynchronous socket handling, through the use of AyncCallBack, uses IO completion ports Ďunder the hoodí, and thus affords all of the performance bonuses of using this model, with none of the complexity.

This model is described in detail, with source code in the book, Network Programming in .NET (at Amazon UK) (at Amazon US)




Google

Copyright 2017 Infinite Loop Ltd.