VB Winsock Control - Have you worked hard with it?

Started by
3 comments, last by owl 21 years, 6 months ago
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]
[size="2"]I like the Walrus best.
Advertisement
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.
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 IfEnd Sub      


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

[edited by - xaxa on October 3, 2002 2:41:20 AM]
[size="2"]I like the Walrus best.
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!    DoEventsEnd 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
Thank you, I''ve been missing some merged packets I think...
[size="2"]I like the Walrus best.

This topic is closed to new replies.

Advertisement