• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 845
  • Last Modified:

Using Winsock to communicate with multiple devices SIMULTANEOUSLY in VB6

I have a program in VB6 currently using winsock to send commands to external devices to extract certain data from them.
But right now, I used timers to schedule when each devices to be read/ to extract data from.

How should I go about using winsock to communicate to different devices (each device got its own IP Address) simultaneously?
And how do I schedule the delay between each communication to a device?

eg.
           Ethernet                         Ethernet
PC ------------------------ Switch------------ Device 1
                                              |
                                              ------------ Device 2
                                              |
                                              ------------ Device 3
                                                   :
                                                   .
                                              ------------ Device n

Scenario:
I want to use PC to extract data from device 1, device 2, ... , device n simultaneouly.
How should I go about doing that?

Right now, I can only extract data from devices in sequence. eg. device 1, then device 2, ...

And how do I provide a interval between each extractions from devices?
Can I use a common timer for all devices?

Please try not to use ActiveX dll type, as I have already written all the necessary communication routines in normal EXE file.
What I need now is to be able to share these routines to communicate with devices simultaneously, not sequentially.
0
jcwh
Asked:
jcwh
  • 14
  • 12
  • 11
  • +1
1 Solution
 
osmodeanCommented:
By using a collection of timers and a collection of winsock controls, you can pull of simultanous communication.
This way you use 1 timer and 1 winsock control for each device you want to extract information from.

I hope that this helps!

Osmodean
0
 
jcwhAuthor Commented:
When I tried to do that, some how when the device 1 communicates, it cut off device 0 communications.

Do you have an example to illustrates 2 simultaneous winsock communication?

But putting one timer for one deivce will cause the CPU usage to be high.
0
 
osmodeanCommented:
You can use 1 timer for all your timing needs, thats not a problem.
Just declare global variables to hold timer information for all devices.

private m_time as long
private m_device1 as boolean
private m_device2 as boolean
private m_device1_time as long
private m_device2_time as long

in your timer subroutine:
m_time = m_time + 1
if m_device1 then
 if m_time >= m_device1_time then
  ' do stuff for device1
  m_device1 = false
  m_device1_time = 0
 end if
end if
if m_device2 then
 if m_time >= m_device2_time then
  ' do stuff for device2
  m_device2 = false
  m_device2_time = 0
 end if
end if

to start timing for a device do this:
m_device1_time = m_time + interval
m_device1 = true

This should resolve your timing issue
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
osmodeanCommented:
for simultanous communication with devices:
you use different ips but are you communicating on the same port?

imo it shouldnt give any problems when you use a different winsock for every device if you use different ips and different communication ports.

I hope this helps!
0
 
jcwhAuthor Commented:
I'm using the same port, but with different IP addresses.
Can I still perform simulaneously communications?
0
 
jcwhAuthor Commented:
What I mean is the external devices have different IP addresses, but all are configured using the same port number, 502.
0
 
jcwhAuthor Commented:
Can I let Winsock to use a port for each devices and point to devices of port 502?

eg.

  PC      ------------------    Device 1
Port 21                            Port 502

  PC      ------------------    Device 2
Port 22                            Port 502

How am I going to go go about doing the above mentioned?
0
 
osmodeanCommented:
that should work just fine using winsock
the winsock control uses asynchronous datatransfer, so basically winsock sends data to a device, then waits untill it receives data  from that device (and triggers an event to let you know data has been received).

without some code it is hard to see what might be wrong, perhaps you can post some.
0
 
jcwhAuthor Commented:
Dim bPoll As Boolean 'TRUE if corresponding timer function is executing
Dim b1stTimePoll As Boolean 'TRUE if it is the first run of timer function

Private Sub TimerPoll_Timer()
    If bTimerPoll2 = True Then      '(If bTimerPoll2 = True, meaning other timer is executing, so wait for TimerPoll's turn)
        TimerPoll.Interval = 10000   '(Interval for TimerPoll to check if it is time to run PollDevice)
        Exit Sub
    End If
   
    If bPoll = True Then
        Exit Sub
    Else
        bPoll = True
    End If
   
    If b1stTimePoll Then
        b1stTimePoll = False
        TimerPoll.Interval = 10000
    Else
        If DateDiff("s", lastD300PollTime, Now) < iD300Itvl Then '* 60 Then
            If bPoll = True Then
                bPoll = False
            End If
            Exit Sub
        Else
            lastD300PollTime = Now
        End If
    End If
   
    Call PollDevice           '(Function to extract data from Device 1)
   
    Sleep 1000
    Socket300.Close
    bD300conn = False

    bPoll = False
End Sub

0
 
osmodeanCommented:
I dont know exactly why you are coding your timer procedure like that, but I would code it like this:

in general declaration section:
private m_time as long ' number of ticks of the timer
private m_device1 as boolean
private m_device1_time as long

in form load event:
m_time = 0
m_device1 = false
m_device1_time = 0
TimerPoll.Interval = 10000
TimerPoll.Enabled = True
' I want to check device1 in 60 seconds
m_device1_time = m_time + 6 ' 6 cause the interval is every 10 seconds
m_device1 = True

in timer procedure:
m_time = m_time + 1
if m_device1 then
 if m_time >= m_device1_time then
  Call PollDevice
  m_device1 = false
  m_device1_time = 0
 end if
end if

in PollDevice you do all socket calls
generally its a bad idea to put a sleep in a timer function, also making ur app sleep for 1000 milliseconds means your app will not respond for a second. this will show to the user as a frozen application.
you should use the events of winsock to to close a certain connection imo.

I hope this helps a bit!
0
 
nffvrxqgrcfqvvcCommented:
Just create the function to get each all device informationput the information into a textbox and send all the data at once back to you.

When you say device are your refering to recieving hardware information on the computer thats running the server?

Make sure you are allowing your winsock control to accept muliple connections that way you can connect to multiple computer at once.
0
 
nffvrxqgrcfqvvcCommented:
Are each of the PC on a local area network? They might contain a different IP but if your trying to poll device data on your LAN then you can broadcast the connection instead of connecting to each individual PC itself.
0
 
jcwhAuthor Commented:
How do I set to allow winsock to accept multiple connections at a time?
0
 
nffvrxqgrcfqvvcCommented:
http://members.lycos.co.uk/optonline/vbhelp/winsock/

Download wmconnect.zip

Shows how to use winsock to allow multiple connections.

If the page says its not allowed just wait a few seconds it will redirect you to be bale to download the file [wmconnect.zip]
0
 
osmodeanCommented:
egl1044,

you just use a collection of winsock controls to achieve multiple connections
thats exactly what I already have suggested some posts before.
0
 
jcwhAuthor Commented:
egl1044,

wmconnect only shows connection to a single server/client.
0
 
nffvrxqgrcfqvvcCommented:
yes but it allows multiple connections..u can load 10 instances of your clien and connect to the server.

if you have 10 ips open 10 clients and you can connect to each PC.

or you can loop throught the ip's from an array and autoconnect each Ip address with 1 client
0
 
jcwhAuthor Commented:
I do not want to open so many instances of a program. This will cause a problem to switch from one program to another, not confusing when you tab between so many instances.
0
 
osmodeanCommented:
jcwh,

Just use 1 winsock control for every connection to a device you need to make.
You can make a control collection of winsock controls and load/unload more winsock controls at runtime when you need to.
This way memory usage will be minimal.

to make a control collection of winsock controls, add 1 winsock control on your form and put its index property to 0
to load more controls at runtime just use code similar to this:
load winsock(1)
to unload the control:
unload winsock(1)

I hope this helps!

Osmodean
0
 
nffvrxqgrcfqvvcCommented:
Thats what my example project shows osmodean, anyway you could create and array of the ip address and connect to each ip and pull device data from each ip address in the array, if u want to just use 1 client. I never done it  but it might work..
0
 
jcwhAuthor Commented:
But if I put the IP addresses in an array, then it will be kind of sequential already.
Each devices may take up to a minute to complete the extraction of data, so I don't want the second device to wait for the first one to finish then the second and third devices can proceed.
0
 
osmodeanCommented:
you dont put the ip addresses in an array jcwh, you put winsock controls in an array.

On your form create a winsock control 'winsock1' with index 0
index 0 means that you create a control array, this is an array of winsock controls in this case, the index is the position of that winsock control in that array.
If you create another winsock control and give it the same name 'winsock1', you will notice that visual basic automatically sets its index to 1.
You can add winsock controls like that at designtime BUT you can also add and remove them at runtime!!
This would be the ideal solution for you!

' connect to device0 with winsock1(0) and send the command
load winsock1(1)
' connect to device1 with winsock1(1) and send the command
load winsock1(2)
' connect to device2 with winsock1(2) and send the command

You might think that this uses alot of memory, but thats not true! when your program has finished receiving information from a device you can unload the corresponding winsock control!

' finished receiving data from device2
unload winsock1(2)
' finished receiving data from device1
unload winsock1(1)
' finished receiving data from device0
' you cant unload index 0 cause it maintains the control array and you need it when you want to update the data from the devices again!

I hope that this helps!

Osmodean
0
 
jcwhAuthor Commented:
How am I going to send commands to device 1 without letting the device 0 to finish its subroutine/function?

eg.

Load Winsock(0)
Call Function, Extract1 for device 0 extraction.

Where can I add the Load Winsock(1) and the Call Function, Extract2 for device 1 extraction ?
To achieve a virtual simultaneously calling the common Extract function for various devices?
0
 
osmodeanCommented:
You use the winsock events to handle the processing of data, closing of connections of the winsock controls etc
The winsock control is asynchronous, this means you dont get an immediate response, the winsock controls notify you when that happens with events.
So all you need to do is make a function that send requests to the devices. And you dont need to load winsock(0) that is already added on designtime.

so basically in pseudeo code:
winsock(0).send_data_to_device_0
load winsock(1)
winsock(1).send_data_to_device_0
load winsock(2)
winsock(2).send_data_to_device_0

I hope this helps!

Osmodean
0
 
osmodeanCommented:
sorry mistake:

so basically in pseudeo code:
winsock(0).send_data_to_device_0
load winsock(1)
winsock(1).send_data_to_device_1
load winsock(2)
winsock(2).send_data_to_device_2
0
 
jcwhAuthor Commented:
After I sent data to many devices, how should I go about receiving the data from these devices?
won't it be messy?

Function:
GetData(device_id, device_type)
device_id will be used in the commands itself


The GetData() will send the pre-coded commands to send to a device. GetData() contains Winsock function calls.

How should I modify the GetData() to deploy the strategy that you mentioned?

Can you provide a more detailed example, let's say to 3 devices.
0
 
jcwhAuthor Commented:
Because if I just send the command to all devices and stop. Then it will be quite straight forward.

But I am actually sending a series of commands at an interval to each devices, so what I need is to be able to run the same function (GetData()) simultaneously, for each devices.

Please pardon me as I am new to Winsock.
0
 
nffvrxqgrcfqvvcCommented:
If I understood you I could help you. But I dont understand anything you are mentioning but let me suggest some things that you might mean.

You want to connect to ie.. 1 IP address and pull data from more than 1 device and send it back to the client??

You want to connect to 3 computers or 3 IPS all at the same time and pull the device data from all 3 computers at the same time??

What do you mean by devices, are you pulling hardware information from the IP(computer you connecting to) and getting the hardware information and you want to send all that information back to the client at once?

Creating multiple connections with winsock means that the server will allow more than 1 connection at a time, meaning if 4 people have your client all 4 can connect to the same server.exe on the same IP address(or computer).

0
 
osmodeanCommented:
You process the data with the events of the winsock control.
I suggest you read up on winsock events and how to work with them.
MSDN is a good start for this.
0
 
nffvrxqgrcfqvvcCommented:
I agree, however I put together another example project. This is my interpretation of what you mean by sending the device information all at once. I store all infromation on the server into an array and send all information at once. The example does not use multiple connections but you can look at my previous example and edit this example to allow multiple connections.

http://www.members.lycos.co.uk/optonline/vbhelp/example/

Regards,
EGL
0
 
jcwhAuthor Commented:
I want to connect to 3 computers or 3 IPS all at the same time and pull the device data from all 3 computers at the same time.

The devices that i'm referring are actually Meters, PLC using Modbus Protocol.
So I want to send commands to read the status of the registers in them.
And to do this, at times, I have to send a series of commands to read certain registers.
At the same time, I also want to receive every response from the devices in response to whatever commands that I have sent.

eg.

Send: Command A
Send: Command B
Send: Command C
Receive: Response A
Receive: Response B
Receive: Response C
0
 
nffvrxqgrcfqvvcCommented:
You should store the information into an array on your server applications this way you can load all the information to the array and then send the data back to you at once. as far as connecting to 3 ips at the same time if you are connecting to computers on a LAN then you can broadcast the winsock connection so instead of putting the ip address you would broadcast it using something like 255.255.255.0 which means when u senddata to the server all servers that are open on each computer will recieve your senddata command.

Instead of getting each device 1 by just add all 3 devices to an array and store the data into the array and send it all back to you at once.

If you look at my simple example it shows how that can be done.
0
 
nffvrxqgrcfqvvcCommented:
Basically this is how you could send all the information back at once instead of sending 1 command at a time
'If the devices change then just add the array to a Timer and set the interval to update every minute or so if neccesary
Form_Declerations
Dim I
Dim ModBus(0 to 2)

Form_Load on server

'Create array


ModBus(0)=response a
ModBus(1)=response b
ModBus(2)=response c

That will store the data then to send it all at once back to you just add this to Winsock_DataArrival

For I = 0 to 2
winsock1.senddata modbus(I)
'Add a sleep call here so the data doesnt send all on 1 line.
Sleep 300 or 500
Doevents
next I

'what that will do is send all 3 device information bak to the client at once.
0
 
jcwhAuthor Commented:
How do I receive the data?
Any example on receiving?
You only provided sending example.
0
 
nffvrxqgrcfqvvcCommented:
If you download my project it shows how you recieve the sent data.
0
 
nffvrxqgrcfqvvcCommented:
Look in the clients data arrival even located in the winsock control.
0
 
moduloCommented:
PAQed with no points refunded (of 500)

modulo
Community Support Moderator
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 14
  • 12
  • 11
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now