Archived

This topic is now archived and is closed to further replies.

owl

VB Winsock Control - Have you worked hard with it?

Recommended Posts

I have made a client-server application using vb winsock control, and I realized that the packets I send to the cliend can arrive in different order and even not reach client's port. Because of my hurry I was forced to code a queue for output messages and a custom protocol to verify every packet is sent in order and that arrives safely to the client. If not, after n seconds I do a resend of that message. I do validate on client side that I haven't already recieved that message, I use a msg-id number to identify them. Do I am a lammer at this? I'm using TCP-IP protocol, not UDP. I already know that "the TCP protocol, as one of it's requirements, is guaranteed packet delivery, and also guaranteed first-send-first-received packet order" but it seems not to be working with Visual Basic Winsock Control. I post this, because if this is a common issue to winsock, it could be usefull, and if it isnt it could be usefull to take me as a bad example: "you shouldn't do like xaxa did". Either way I could learn, so please if you have worked extensively with this control, and you feel you want, teachme. Thanks in advance.- [edited by - xaxa on October 2, 2002 4:40:49 AM]

Share this post


Link to post
Share on other sites
You are definetly doing something wrong. TCP/IP Guaranties the packet be IN whole, and IN order. The thing that it doesn''t guarantee is that each _DataArrival will be one packet. You can get split data and merged data within there. You could, A.) Send the size of the data first, then the data, so when it arrives, you know how much to get, and if you dont'' have enough, you know that you have to wait for the next DataArrival call before getting the data. Also, make sure that once you are in the DataArrival function, it doesn''t trigger again until you''re done processing the data (this would make it seem out of order!).

Billy - BillyB@mrsnj.com

ps. I have, and am still working on, a Guaranteed socket (I call it GSocket) that basically Guarantees your packet will arrive, in order, never fragmented, and never merged with another packet (using the ideas I posted above). It is written in VB as an Active X control, and uses the normal Winsock control with TCP/IP to work.

Share this post


Link to post
Share on other sites
Thank you Ready4Dis, I'm currently doing this:


      
Private Sub Socket_DataArrival(Index As Integer, ByVal bytesTotal As Long)
If Socket(Index).State = sckConnected Then
Dim tmpBuff As String
Socket(Index).GetData tmpBuff, vbString

If Not m_arrClientData(Index).bWaitingForMore Then
m_arrClientData(Index).lBufferLen = Left(tmpBuff, InStr(tmpBuff, "|") - 1)
m_arrClientData(Index).sInputBuffer = m_arrClientData(Index).sInputBuffer & Right(tmpBuff, Len(tmpBuff) - InStr(tmpBuff, "|"))
m_arrClientData(Index).bWaitingForMore = True
Else
m_arrClientData(Index).sInputBuffer = m_arrClientData(Index).sInputBuffer & tmpBuff
End If

If Len(m_arrClientData(Index).sInputBuffer) < m_arrClientData(Index).lBufferLen Then
m_arrClientData(Index).bWaitingForMore = True
tmpBuff = ""
Else
If Len(m_arrClientData(Index).sInputBuffer) > m_arrClientData(Index).lBufferLen Then
m_arrClientData(Index).sInputBuffer = Left(m_arrClientData(Index).sInputBuffer, m_arrClientData(Index).lBufferLen)
RaiseEvent LogText("
Buffer is bigger than expected")
End If

If m_bEncrypt Then
m_arrClientData(Index).sInputBuffer = Decrypt(m_arrClientData(Index).sInputBuffer, ENCRYPT_PASSWORD)
End If

tmpBuff = m_arrClientData(Index).sInputBuffer
tmpBuff = CheckDuplicateMessage(Index, tmpBuff)

If tmpBuff <> "
" Then
RaiseEvent DataRecieved(Index, tmpBuff)
End If

m_arrClientData(Index).sInputBuffer = "
"
m_arrClientData(Index).lBufferLen = 0
m_arrClientData(Index).bWaitingForMore = False
End If
End If
End Sub


[edited by - xaxa on October 2, 2002 10:22:48 AM]

[edited by - xaxa on October 3, 2002 2:41:20 AM]

Share this post


Link to post
Share on other sites
Looks like you''re missing some stuff in there. Like, forgetting the fact, that packets can be merged, aka, you send 2 packets, and they arrive together. If this is the case, you have to split the line up, and handle both sections seperately. Also, the DataArrival even can trigger WHILE in the DataArrival function, so you should make something that only allows it to enter once at a time, and keeps looping until all data is done. This is my DataArrival function in my GScoket. It sends the size of packet as a long, so each "packet" has a 4byte overheard ontop of any other overhead, but this way I don''t have to check packet sizes in my main program (which would have caused it''s own over-head anyways). Also, it calls a Crypt function (it has built in encryption in the ActiveX control, so I dont'' have to worry about that in my main programs either). You can simply omit this function and it''ll be "normal" data.


  
Private Sub wskMain_DataArrival(ByVal bytesTotal As Long)
Dim Dt As String
Dim JustGot As Long

If InFunction = 1 Then Exit Sub

InFunction = 1 ''We''re in the function, so don''t come in again until done!

CheckAgain: ''We gotta loop through just incase more than 1 packet is here!
''Check if we have enough data to get a size if we have none!
If Get_Size = 0 And bytesTotal > 3 Then
wskMain.GetData Get_Size, vbLong, 4 ''Get the size of the packet
bytesTotal = bytesTotal - 4 ''Subtract 4 bytes (long) from our total
Got_Size = 0
End If

If Got_Size < Get_Size Then ''Do we need more?
wskMain.GetData Dt, vbString, Get_Size - Got_Size ''Get some data, but only as much as needed damnit!
JustGot = Len(Dt) ''Get the length of what we just got!
Got_Size = Got_Size + JustGot ''We got this many, so add it
bytesTotal = bytesTotal - JustGot ''Take this off our total
In_Buffer = In_Buffer & Dt ''Append what we just got!
If Get_Size = Got_Size Then ''Do we have what we need?
RaiseEvent PacketArrival(Get_Size, Crypt(In_Buffer, EncryptionKey)) ''Trigger our event
Get_Size = 0 ''Don''t need any more!
Got_Size = 0 ''We ain''t Got nothing anymore :)
In_Buffer = "" ''Nothing in here now
bytesTotal = wskMain.BytesReceived ''How many bytes left in our buffer to receive!
If bytesTotal > 3 Then ''We still have crap here...
GoTo CheckAgain ''We''ve got enough for a size header still, so CheckAgain
End If
End If
End If
InFunction = 0 ''No longer in it!
DoEvents
End Sub


It''s not 100% complete, but should give you an idea on what i''m doing. If you have any questions, feel free to ask/email me. (Email works better, because i don''t check old posts much).

Billy - BillyB@mrsnj.com

Share this post


Link to post
Share on other sites