Managing two simultaneous Winsock connections
ve buillt an app which establishes 2 winsock connections simultaneously. The IP for both sockets is the same, but ports are different.
Code:
With Winsock1
.RemoteHost = "255.255.255.255"
.RemotePort = 1002
.Bind 1001
End With
With Winsock2
.RemoteHost = "255.255.255.255"
.RemotePort = 1004
.Bind 1003
End With
I receive a data stream on both the IPs, which I then parse and display in my application. The data coming in is received by Databyarrival method. It works fine for the most part. However, there are certain instances, where one of the broadcasts freezes up, while the other is still running.
Any idea why one broadcast may freeze up randomly, and what can be done to avoid this?
Re: Managing two simultaneous Winsock connections
There's a million and one possible reasons. Could you post the code for the DataArrival events please - that's normally the most problematic area.
Re: Managing two simultaneous Winsock connections
Code:
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim strData As String
Winsock1.GetData strData
strfield0 = vbNullString
'The following code parses the datafeed that I receive on the port.
For x = 1 To 10 Step 1: strfield(x) = vbNullString: Next x
For x = 1 To 24 Step 1: strfield1(x) = vbNullString: Next x
For x = 1 To Len(strData) Step 1
chrchk = Mid(strData, x, 1)
If chrchk <> "~" Then strfield0 = strfield0 & chrchk
Next x
y = 1
For x = 1 To Len(strfield0) Step 1
chrchk = Mid(strfield0, x, 1)
If chrchk <> "|" Then
strfield(y) = strfield(y) & chrchk
ElseIf chrchk = "|" Then
y = y + 1
End If
Next x
y = 1
For x = 1 To Len(strfield(9)) Step 1
chrchk = Mid(strfield(9), x, 1)
If chrchk <> ";" Then
strfield1(y) = strfield1(y) & chrchk
ElseIf chrchk = ";" Then
y = y + 1
End If
Next x
y = 1
For z = 1 To 10 Step 1
ucasestr(z) = UCase(txtSymbol(z).Text)
If strfield1(2) = ucasestr(z) And strfield(7) = "?REGCO.?." Then
txtPrice11(z).Text = strfield1(6): txtVolume11(z).Text = strfield1(5)
txtPrice22(z).Text = strfield1(7): txtVolume22(z).Text = strfield1(8)
End If
Next z
For z = 1 To 10 Step 1
If txtPrice11(z).Text <> "" And txtPrice2(z).Text <> "" Then
DiffPriceIP = Val(txtPrice11(z).Text) - Val(txtPrice2(z).Text)
txtPriceDiffIP(z).Text = DiffPriceIP
End If
Next z
strData = vbNullString
End Sub
And the second is....
Code:
Private Sub Winsock2_DataArrival(ByVal bytesTotal As Long)
Dim strData4011 As String
Dim array4011(1 To 21) As String
Dim array4011a(1 To 11) As String
Winsock2.GetData strData4011
'The following is to parse the stream that i receive.
For a = 1 To 21
array4011(a) = vbNullString
Next
For a = 1 To 11
array4011a(a) = vbNullString
Next
b = 1
For a = 1 To Len(strData4011)
ChrChk4011 = Mid(strData4011, a, 1)
If ChrChk4011 <> ";" Then
array4011(b) = array4011(b) & ChrChk4011
ElseIf ChrChk4011 = ";" Then
If b < 10 Then b = b + 1
End If
Next
For a = 1 To Len(array4011(1))
ChrChk4011 = Mid(array4011(1), a, 1)
If ChrChk4011 <> "|" Then
SymbolParse = SymbolParse & ChrChk4011
ElseIf ChrChk4011 = "|" Then
Exit For
End If
Next
If SymbolParse = "@@PLAIN_UDP@@FEED" Then
For a = Len(array4011(1)) To 1 Step -1
ChrChk4011 = Mid(array4011(1), a, 1)
If ChrChk4011 <> "|" Then
Symbol4011 = Symbol4011 & ChrChk4011
ElseIf ChrChk4011 = "|" Then
Exit For
End If
Next a
End If
Symbol4011 = StrReverse(Symbol4011)
For a = 1 To 10
If txtSymbol(a).Text = Symbol4011 And array4011(2) = "T-REG" Then
txtPrice1(a).Text = Val(array4011(6))
txtPrice2(a).Text = Val(array4011(7))
End If
If txtPrice1(a).Text <> "" And txtPrice22(a).Text <> "" Then
DiffPrice = Val(txtPrice1(a).Text) - Val(txtPrice22(a).Text)
txtPriceDiff(a).Text = DiffPrice
End If
Next a
strData4011 = vbNullString
End Sub
Whats noteworthy is that if i run one socket connection at a time, it never freezes. But if i run both in the same application, Winsock1 freezes randomly....but Winsock2 does not freeze.
Any help?
Thanks
Re: Managing two simultaneous Winsock connections
Well, to start with, you don't seem to have an Application Protocol. In your DataArrival events how do you know when you've received a complete record? A common misapprehension is that if I issue a SendData it will generate a DataArrival event at the other end. That is not necessarily true. A SendData may or may not generate one or more DataArrival events. Uisng TCP and IP the only assumption you can make is that all the data will eventually arrive (or an error will be raised) and the data will arrive in the same order in which it was sent. You have to perform Buffer Management in your code to cater for all situations.
What are the symptoms of "freezing"!? Is Winsock1 busier than Winsock2?
Re: Managing two simultaneous Winsock connections
Being a novice, i only know so far as to receive data through the getdata component. Each batch of data that i receive is separated by a line separator, which i assume tells the app that one complete record has arrived. And that seems to be true when i run only one of these 2 at a time. But it is only when I run them both in the same application simultaneously, that this freeze occurs.
Yes, winsock1 is busier than winsock2. Both are UDP ports.
What is application protocol, and how do i perform buffer management in this case? sorry for the primitive queries, but im a beginner at this. Thanks.
Re: Managing two simultaneous Winsock connections
Ok, you might like to read Post#5 of this thread http://www.vbforums.com/showthread.php?t=502379 (to save me typing it all in again) :)
Is there any particular reason you're using UDP as opposed to TCP? UDP is not a 'reliable' protocol, in other words if packets go astray the protocol doesn't care or report the fact, whereas TCP is a 'reliable' protocol and delivery is guaranteed (or an error is raised)
Re: Managing two simultaneous Winsock connections
I am using UDP because that is the protocol on which the data is coming in, so I guess i have no other choice. Or do ? Is it possible for me to use TCP while the incoming data is using UDP?
Ive given your post a read, and am trying to understand it. Thanks for the reference. In the meantime, if you have any ideas regarding this code above, do let me know.
Thanks again.
Re: Managing two simultaneous Winsock connections
Ok.I'll take a further look...
Re: Managing two simultaneous Winsock connections
Hi Style,
it sounds as if you don't have the control over the format of the data that is coming in. So you can't change anything on the sending side ( and you are stuck with UDP).
It looks to me as if you might be getting several messages in during a single run of the dataArrival sub. Don't you get anything for a ending sign of a message?, because that would help to seperate the messages (which might be both in your strData!
Have a look along this way!
Re: Managing two simultaneous Winsock connections
OK, in Post #5 you mention a 'line separator'. Assuming that is a vbNewLine then the following will provide you with some buffer management.(Winsock1)
Code:
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim strData As String
Static strBuffer As String
Dim lngPos As Long
Dim boFinished As Boolean
Winsock1.GetData strData
strBuffer = strBuffer & strData
Do
lngPos = InStr(strBuffer, vbNewLine)
If lngPos > 0 Then
'
' There's at least 1 complete record in the buffer
' unblock it and process it
'
strdata = Mid$(strBuffer,1,lngpos)
strfield0 = vbNullString
'The following code parses the datafeed that I receive on the port.
For x = 1 To 10 Step 1: strfield(x) = vbNullString: Next x
For x = 1 To 24 Step 1: strfield1(x) = vbNullString: Next x
For x = 1 To Len(strData) Step 1
chrchk = Mid(strData, x, 1)
If chrchk <> "~" Then strfield0 = strfield0 & chrchk
Next x
y = 1
For x = 1 To Len(strfield0) Step 1
chrchk = Mid(strfield0, x, 1)
If chrchk <> "|" Then
strfield(y) = strfield(y) & chrchk
ElseIf chrchk = "|" Then
y = y + 1
End If
Next x
y = 1
For x = 1 To Len(strfield(9)) Step 1
chrchk = Mid(strfield(9), x, 1)
If chrchk <> ";" Then
strfield1(y) = strfield1(y) & chrchk
ElseIf chrchk = ";" Then
y = y + 1
End If
Next x
y = 1
For z = 1 To 10 Step 1
ucasestr(z) = UCase(txtSymbol(z).Text)
If strfield1(2) = ucasestr(z) And strfield(7) = "?REGCO.?." Then
txtPrice11(z).Text = strfield1(6): txtVolume11(z).Text = strfield1(5)
txtPrice22(z).Text = strfield1(7): txtVolume22(z).Text = strfield1(8)
End If
Next z
For z = 1 To 10 Step 1
If txtPrice11(z).Text <> "" And txtPrice2(z).Text <> "" Then
DiffPriceIP = Val(txtPrice11(z).Text) - Val(txtPrice2(z).Text)
txtPriceDiffIP(z).Text = DiffPriceIP
End If
Next z
'
' Processing is complete for this record
' Now check if there's anything else in the Buffer
'
If lngPos < Len(strBuffer) Then
'
' Yes there is, shift it to the front of the buffer
' and go round the loop again
'
strBuffer = Mid$(strBuffer, lngPos + 2)
Else
'
' Flush the buffer and signal to exit the loop
'
strBuffer = ""
boFinished = True
End If
Else
'
' Havent got a complete record yet so just exit
'
boFinished = True
End If
Loop Until boFinished = True
End Sub
If the 'Line separator' is just vbLf then make the following changes
Code:
lngPos = InStr(strBuffer, vbNewLine)
'
' change to
'
lngPos = InStr(strBuffer, vbLf)
'
' and
'
strBuffer = Mid$(strbuuffer, lngPos + 2)
'
' change to
'
strBuffer = Mid$(strBuffer, lngPos + 1)
There may be a few typos in the code I've added as it's not tested but hopefully you can see the logic.
Re: Managing two simultaneous Winsock connections
Many thanks Doogle for your help. Im giving it a try as we speak. Will get back to you on it.
Just to mention, the line separator that is being used is the ~ sign. Is that the same as VBnewLine? pardon my ignorance.
Re: Managing two simultaneous Winsock connections
No, it's not the same. You'll need to make a couple of changes:
Code:
lngPos = InStr(strBuffer, vbNewLine)
'Change to
lngPos = InStr(strBuffer,"~")
'and
strBuffer = Mid$(strBuffer, lngPos + 2)
'change to
strBuffer = Mid$(strBuffer, lngPos + 1)
Re: Managing two simultaneous Winsock connections
Re: Managing two simultaneous Winsock connections
My pleasure
If it's working ok with Winock1 I suggest you put the same logic into the Winsock2 DataArrival event.