Winsock Control - Multi-connections

  I have used the following server code successfully to establish a connection with a client program and receive data from the client.  I took the code right out of the Books Online TCP server example and made just a couple minor modifications.  This is what I have...

Private Sub Form_Load()
    ' Set the LocalPort property to an integer.
    ' Then invoke the Listen method.
    tcpServer.LocalPort = 2345
End Sub

Private Sub tcpServer_ConnectionRequest _
(ByVal requestID As Long)
    ' Check if the control's State is closed. If not,
    ' close the connection before accepting the new
    ' connection.
    If tcpServer.State <> sckClosed Then _
    ' Accept the request with the requestID
    ' parameter.
    tcpServer.Accept requestID
End Sub

Private Sub txtSendData_Change()
    ' The TextBox control named txtSendData
    ' contains the data to be sent. Whenever the user
    ' types into the  textbox, the  string is sent
    ' using the SendData method.
    tcpServer.SendData txtSendData.Text
End Sub

Private Sub tcpServer_DataArrival _
(ByVal bytesTotal As Long)
    ' Declare a variable for the incoming data.
    ' Invoke the GetData method and set the Text
    ' property of a TextBox named txtOutput to
    ' the data.
    Dim strData As String
    tcpServer.GetData strData
    txtOutput.Text = strData
End Sub

What I want to do is allow multiple connections.  Books Online gives this code to achieve that purpose...

Private intMax As Long

Private Sub Form_Load()
      intMax = 0
      sckServer(0).LocalPort = 1001
End Sub

Private Sub sckServer_ConnectionRequest _
(Index As Integer, ByVal requestID As Long)
      If Index = 0 Then
            intMax = intMax + 1
            Load sckServer(intMax)
            sckServer(intMax).LocalPort = 0
            sckServer(intMax).Accept requestID
            Load txtData(intMax)
      End If
End Sub

Being such a beginner, I don't fully understand this latter part and was wondering if anyone could put the 2 pieces of code together for me to make it work for accepting multiple connections.  I'm having a tough time visualizing what would happen when a subsequent connection request is made since this latter code only addresses the possibility of Index = 0, and does not have an 'else if' or an 'else' attached to the 'sckServer_ConnectionRequest' routine.  Thanks in advance
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Wow, where do I begin ...
Give me 20-30 minutes and I'll work up an answer and post it here. Don't grade me until I've posted my next submission

============> Frederick Volking

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
First let me applaude your effort. The approach you’re taking is wonderful. Find some code that does "almost" what you want and learn enough to change it. That’s an absolutely wonderful way to learn!

Okay let’s start with the basics (no pun intended)


We have ONE instance of a variable called X


We have SEVENTY-SIX instances of a variable called X (76 because arrays start at 0 so 1 to 75 = 75 plus 0 = 76)



We have FIFTY instances of a structure called ABC and the structure ABC is composed of a type called MYSTRUC, therefore . . .
We have FIFTY instances of a variable called X
We have FIFTY instances of a variable called Y
We have FIFTY instances of a variable called Z

To address individual variables we first identify which one of the FIFTY possible structures we’re referencing, then we identify which component of the structure MYSTRUC we actually want

ABC(20).X = 99
ABC(50).Z = "Hello"

Hopefully these concepts are familiar to you. This may be over simplistic but I’m not sure of your skill level so I’m starting at ground zero.

Now that I’ve laid that foundation, let’s look at your code.

What you’re dealing with is a "control" which has been named tcpServer. To make visualization easier, let’s imagine that the control tcpServer is really nothing more than a fancy structure. To make multiple instances of a structure you DIMension the structure to a predetermined quantity. If the tcpServer control was a structure made up from several variables, it might look something like this . . .

Type WinSock
          LocalPort as long
          Protocol as string
          State as boolean
          RemoteHost as string
          RemotePort as long
end type
DIM tcpServer(10) as WinSock

If  WinSock was a structure, then the above line would give us 11 instances of the WinSock structure. (Remember, the WinSock control is NOT really a structure but to visualize it this way may help you understand how to handle multiple instances of a control).

Since the WinSock control is not a structure, instead of DIMing 10 instances, we add 10 individual WinSock controls to our form! Make sure to name all 10 controls exactly the same name but set their INDEX to 0, 1, 2, 3, etc . . .

When you’re done, you’ll have 10 instances of the WinSock control, which can be addressed and manipulated as individuals.

And to address any one of them, you’ll need to first identify which (of the ten) you want then then set the property.

Also when an event fires, you’ll need to know which control fired . . . so let’s rewrite your code segments.

Remember, the below code assumes you have 10 copies of the WinSock control on your form and they’re all named WinSock and their Indexes are numbered 1 to 10.

Private Sub Form_Load()
for count% = 1 to 10
WinSock(count%).LocalPort = 2344 + Count%
End Sub

Private Sub WinSock_ConnectionRequest (Index as integer, ByVal requestID As Long)
If WinSock(Index).State <> sckClosed Then WinSock(Index).Close
WinSock(Index).Accept requestID
End Sub

Private Sub txtSendData_Change()
 ‘remember, we’ve got 10 incidents of the WinSock control, to send data out one of them we must FIRST decide which one to use, so I’ve simulated that we have a variable set to determine which WinSock to use
WinSock(WhichWinSock).SendData txtSendData.Text
End Sub

Private Sub WinSock_DataArrival (Index as integer, ByVal bytesTotal As Long)
WinSock(Index).GetData txtOutput.Text
End Sub

The code above here assumes that you have 10 copies of the WinSock control ALREADY on the form. But the code below here is very different . . . and VERY TRICKY.

VB has the ability to create new instances of a control ON-THE-FLY! Instantly! Like Magic! All you need is one copy of the control and you can instruct VB to suddenly create additional copies. This "magic" is done with the LOAD command. Using the Load command in this way is really quite advanced and has several critical limitation and a few real headaches! (such as how to get rid of the controls once you create them because they must be destroyed in the EXACT REVERSE ORDER they were created!) But if you really want to try this method, I’ll try to explain it . . .

Let’s assume your form has one WinSock control called WinSock. Every time that control recieves a ConnectionRequest we’re going to
A) Make a new copy of the existing WinSock control, then
B) Attach the incoming request to the NEWLY CREATED control (NOT the existing control)

First step is to keep track of how many controls we’ve created up until this particular moment in time. So we create a variable with a scope of Module level to track how many instances we have.

Private intMax As Long

Next, when the request come in, . . . .

Private Sub WinSock_ConnectionRequest (Index As Integer, ByVal requestID As Long)
‘first let’s make sure the request is coming from the first instance of the control
If Index = 0 Then
‘yes, it’s coming from the first instance so we increment the count of how many controls we have all together
intMax = intMax + 1
‘then we magically create another instance and assign it’s position to the highest instance
Load WinSock(intMax)
‘then we set it’s local port and tell it to talk to the incoming request
WinSock(intMax).LocalPort = 0
WinSock(intMax).Accept requestID
‘Im not sure what this next line is for . . . except possibly to allow a location to put the incoming text, so we magically create another instance of the TextBox and also assign it’s position to the highest instance
Load txtData(intMax)
End If
End Sub


Okay, that’s what’s happening. But let me warn you, using the LOAD command to magically create additional instances of controls is very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very TRICKY !

There are lots of  problems and it takes a real professional to make it work. I’ve been coding for about 25 years and it’s a task I would not attempt if there was any other approach.

Using the first approach, where you pre-make 10 instances of the control, is a far more "friendly" method, but of course has limitation.

The approach you finally take is your decision. I wish you luck.

Keep going!

============> Frederick Volking

BTW ... You can reach me directly at

========> Frederick Volking
Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

Sorry that's a typo - the correct address is

It's getting late .... I'm hungry ... good night!

zingbustAuthor Commented:
Thanks for spending so much time with this.  My skill level is spotty, so the primer was much appreciated.  I'm not sure how I should approach this because what I'm going to be doing is having a continuous flow of connection requests from my web-site (where the client program resides).  Once the system is up and running, it must run automatically.  I had visualized using the control array to save on memory, but you say the controls have to be destroyed in reverse order from the way they were created, which won't work because at any given time, there may be a number of simultaneous connections that are active.  Surely there must be a way to destroy them as soon as the connections are closed, isn't there?!?!  By the way, by changing my code to reflect the changes you advised, the server program is now able to take multiple requests, however the data does not get displayed in the text box, but that's not important, because this is only a test, anyway.  The real application will be writing the data to a file where it can be opened and acted upon by another part of the total program.  
One approach I've seen work is to establish a limited pool of resources and maintain a set of flags about which connections are in use and which are free. Then, when new connection requests are recieved, scan through the pool looking for a free connection. Also, you might want one "special" connection that is never used except when the pool is used-up. Do a quick connection to the "special" control, dump a message like "Server Too Busy" and force a connection terminate.

Have fun
=============> Frederick Volking
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Programming Languages-Other

From novice to tech pro — start learning today.