VB Winsock Control - Have you worked hard with it?
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]
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.
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:
[edited by - xaxa on October 2, 2002 10:22:48 AM]
[edited by - xaxa on October 3, 2002 2:41:20 AM]
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]
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.
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
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
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement