Results 1 to 10 of 10

Thread: Winsock Data Arrival issue

  1. #1

    Thread Starter
    New Member
    Join Date
    Mar 2006
    Posts
    10

    Winsock Data Arrival issue

    Hey everyone!

    I have quite the issue here.

    Basically my program understands the protocol of a certain Chat server. However, since these packets are sent in rather large quantities sometimes, I have to parse the huge "chunk" into their separate packets. And because they include the length of the packet in the packet header, it is rather easy.

    The problem comes when the data chunk is actually Larger than 8192 Bytes. Winsock unfortunately splits chunks into these 8192 byte sizes which can cause some packets to be split in incorrect places. so I was wondering if there is a way to Know how much data was sent to me, if they send more than 8192 bytes at a time.

    This issue has Plagued me!

    Thanks all

  2. #2
    PowerPoster
    Join Date
    May 2006
    Posts
    2,988

    Re: Winsock Data Arrival issue

    i dont know if this is what you are looking for but ..

    Private FileBytes As Long

    And In Data Arrival ..

    FileBytes = FileBytes + bytesTotal

  3. #3

    Thread Starter
    New Member
    Join Date
    Mar 2006
    Posts
    10

    Re: Winsock Data Arrival issue

    well no, I mean I don't know how to find out just how much data is supposed to come in without tallying it up as the DataArrival is fired.

    The problem is that this is just streamed packets. The server sends me vast amounts of packets all at the same time, so everything is just sloshed together in one huge chunk.

    Sometimes, the chunk exceeds this 8192 byte limit and the Data Arrival is fired more than once! And because of this, there might be one or two packets that are cut in odd places and causes runtime errors.

    What I need to do is really be able to re-assemble these huge chunks BEFORE I start parsing them. I am just not sure how I could really know how much is coming in, or what to buffer.

  4. #4
    Addicted Member
    Join Date
    Mar 2006
    Posts
    178

    Re: Winsock Data Arrival issue

    Hi,
    You said that your packets included the length of the packet? Doesn't this tell you how much data is being sent to your client program?

    What you could do is concantenate all the packets into one string or byte array and then use the packet length to tell your program how much data to process.

  5. #5
    PowerPoster
    Join Date
    May 2006
    Posts
    2,988

    Re: Winsock Data Arrival issue

    in just downloading I parse it all on Winsock Close .. but not sure if that will work in a server project .. once it closes I then handle the response codes, and if its downloading anything other than Text i create a file using the binary.

    Also I get the length from the header if I can ..
    small example .. though it may not apply to what you're doing ..?
    I used this on a couple 180mb files last night ..



    VB Code:
    1. Private ReceiveData         As String
    2. Private FileLength          As Long
    3. Private FileBytes           As Long
    4. Private LengthParsed        As Boolean
    5.  
    6. '// GET DATA
    7. Public Sub WinsockReceive(ByVal bytesTotal As Long)
    8.     Dim strData As String
    9. On Error GoTo Err:
    10.     '// GET DATA
    11.     fWinsock.Winsock1.GetData strData, vbString
    12.     ReceiveData = ReceiveData & strData
    13.     FileBytes = FileBytes + bytesTotal
    14.     '// GET THE HEADER
    15.     If Not LengthParsed Then
    16.         GetLength
    17.     Else
    18.     '// DOWNLOAD FILE
    19.         Download
    20.     End If
    21.     Exit Sub
    22. Err:
    23. '// ERROR HANDLING
    24.     UpdateStatus ("Data Error")
    25.     WinsockDisconnect
    26.     Exit Sub
    27. End Sub
    28.  
    29. '// GET FILE LENGTH
    30. Private Sub GetLength()
    31.     Dim BreakePosition As Integer
    32.     Dim vHeaders As Variant
    33.     Dim vHeader As Variant
    34.     BreakePosition = InStr(1, ReceiveData, vbCrLf & vbCrLf)
    35.     If BreakePosition Then
    36.         LengthParsed = True
    37.         FileBytes = FileBytes - BreakePosition - 3
    38.         vHeaders = Split(Left(ReceiveData, BreakePosition - 1), vbCrLf)
    39.         '// GET THE CONTENT LENGTH
    40.         For Each vHeader In vHeaders
    41.             If InStr(1, vHeader, "Content-Length") Then
    42.                 FileLength = CLng(Mid(vHeader, InStr(1, vHeader, " ") + 1))
    43.                 Exit For
    44.             End If
    45.         Next
    46.     End If
    47. End Sub
    48.  
    49. '// DOWNLOAD
    50. Private Sub Download()
    51.     If FileLength > 0 Then
    52.         UpdateProgress
    53.         UpdateStatus ("Downloading: " & FileBytes & " of " & FileLength & " bytes " & _
    54.         "(" & CInt(FileBytes / (FileLength / 100)) & "%)")
    55.     Else
    56.         UpdateStatus ("Downloading: " & FileBytes & " bytes")
    57.     End If
    58. End Sub
    59.  
    60. '// UPDATE PROGRESS
    61. Private Sub UpdateProgress()
    62.     fWinsock.ProgressBar1.Value = FileBytes / (FileLength / 100)
    63. End Sub
    64.  
    65. '// UPDATE STATUS
    66. Private Sub UpdateStatus(ByVal StatusType As String)
    67.     fWinsock.Caption = StatusType
    68. End Sub
    Last edited by rory; Jun 7th, 2006 at 04:23 AM.

  6. #6
    PowerPoster
    Join Date
    May 2006
    Posts
    2,988

    Re: Winsock Data Arrival issue

    something i use found at vbip.com ..

    VB Code:
    1. '.... in winsock close ..
    2.  
    3.         ReceiveHeader = Left$(ReceiveData, InStr(1, ReceiveData, vbCrLf & vbCrLf) + 1)
    4.         ReceiveData = Mid(ReceiveData, InStr(1, ReceiveData, vbCrLf & vbCrLf) + 4)
    5.    
    6.         If GetHttpHeaderFieldValue(ReceiveHeader, "Transfer-Encoding") = "chunked" Then
    7.             ReceiveData = DecodeChunkedMessage(ReceiveData)
    8.         End If
    9.  
    10.  
    11.  
    12. Private Function GetHttpHeaderFieldValue(strHttpHeader As String, strHttpHeaderField As String) As String
    13.     Dim strBuffer As String
    14.     Dim intStart As Integer
    15.     Dim strSearchString As String
    16.     strSearchString = vbCrLf & strHttpHeaderField & ": "
    17.     intStart = InStr(1, strHttpHeader, strSearchString) + Len(strSearchString)
    18.     strBuffer = Mid$(strHttpHeader, intStart, InStr(intStart, strHttpHeader, vbCrLf) - intStart)
    19.     If Len(strBuffer) > 0 Then
    20.         GetHttpHeaderFieldValue = strBuffer
    21.     End If
    22. End Function
    23.  
    24. Private Function DecodeChunkedMessage(strMessage As String) As String
    25.     'This is a scheme of chunked message
    26.     '<CHUNK SIZE><CRLF><DATA CHUNK><CRLF><CHUNK SIZE><CRLF><DATA CHUNK>...<0 CHUNK SIZE>
    27.     Dim lngPosA As Long
    28.     Dim lngPosB As Long
    29.     Dim intOctetsToRead As Integer
    30.     Dim strTempBuffer As String
    31.     Const CRLF_LENGHT = 2
    32.     lngPosA = InStr(1, strMessage, vbCrLf)
    33.     intOctetsToRead = Val("&H" & Left(strMessage, lngPosA - 1))
    34.     Do Until intOctetsToRead = 0
    35.         strTempBuffer = strTempBuffer & Mid(strMessage, lngPosA + CRLF_LENGHT, intOctetsToRead)
    36.         lngPosB = lngPosA + CRLF_LENGHT + intOctetsToRead + CRLF_LENGHT
    37.         lngPosA = InStr(lngPosB, strMessage, vbCrLf)
    38.         intOctetsToRead = Val("&H" & Mid(strMessage, lngPosB, lngPosA - lngPosB))
    39.     Loop
    40.     DecodeChunkedMessage = strTempBuffer
    41. End Function

  7. #7

    Thread Starter
    New Member
    Join Date
    Mar 2006
    Posts
    10

    Re: Winsock Data Arrival issue

    davidbishton:
    They only give the length of each individual packet. And since TCP is a streaming protocol, all the packets get mashed together in a gargantuan chunk if it's sent in a continuous stream.

    IF this stream exceeds 8192 bytes, they fire the Winsock Data_Arrival() event more than once causing errors.

    rory:
    I see what you are trying to do, but it doesn't really apply to the type of protocol I'm trying to parse.

    Think of it this way:

    If a packet is at the end of this huge 8192 byte size Chunk, it might get cut off, and the second half of the packet would get fired through the Data_Arrival() event. And since the second half of the packet must go through the SAME parsing process as the first half, obvioulsy it would cause error. I don't think I'm explaining this correctly, but I hope you understand...

    Thanks rory for all this code though..

  8. #8
    KING BODWAD XXI BodwadUK's Avatar
    Join Date
    Aug 2002
    Location
    Nottingham
    Posts
    2,176

    Re: Winsock Data Arrival issue

    What you need to do is split down your chunks and then work out if the final chunk is the correct length (from the chunk header). If it isnt then store it in a static variable until the next packet arrives. Add the remainder of the last message to the front of the new one and bingo its in order.
    VB Code:
    1. Private Sub Winsock1_dataarrival(BytesTotal as integer)
    2. Static Remainder as string
    3. Dim strData as string
    4.  
    5.      'Get your new packet
    6.      winsock1.getdata strData
    7.  
    8.     'Merge the remainder of the last one to this new one
    9.     strData = Remainder & strdata
    10.  
    11.     'Break down you message and until no more chunks are complete
    12.  
    13.     'Move any data from an uncompleted chunk to the remainder variable for the next arrival event
    14.     Remainder = (RestOfChunk) 'Whatever was left unprocessed
    15.    
    16.    
    17. end Sub
    If you dribble then you are as mad as me

    Lost World Creations Website (XBOX Indie games)
    Lene Marlin

  9. #9
    PowerPoster
    Join Date
    May 2006
    Location
    Location, location!
    Posts
    2,673

    Re: Winsock Data Arrival issue

    I know this is an old post I'm replying to, but I've been using the above DecodeChunkedMessage code in a project of mine for a while, and for the first time yet it's encountered a block size over 8192. I've managed to isolate the problem down to this one specific line:
    vb Code:
    1. intOctetsToRead = Val("&H" & Left(strMessage, lngPosA - 1))
    Using &H like this is returning the value -28398 for a block whose length in hex is 9112 when the data's length is actually 37138 (I converted hex to decimal with http://www.statman.info/conversions/hexadecimal.html and it returned the value correctly). Is there a more robust way to convert the hexadecimal value 9112 (or anything over 2000 in hex (that's 8192 :-P) to decimal?
    Well, everyone else has been doing it :-)
    Loading a file into memory QUICKLY - Using SendKeys - HyperLabel - A highly customisable label replacement - Using resource files/DLLs with VB - Adding GZip to your projects
    Expect more to come in future
    If I have helped you, RATE ME! :-)

    I love helping noobs with their VB problems (probably because, as an amateur programmer, I am only slightly better at VB than them :-)) but if you SERIOUSLY want to get help for free from a community such as VBForums, you have to first have a grounding (basic knowledge) in VB6, otherwise you're way too much work to help...You've got to give a little if you want to get help from us, in other words!

    And we DON'T do your homework. If your tutor doesn't teach you enough to help you make the project without his or her help, FIND A BETTER TUTOR or try reading books on programming! We are happy to help with minor things regarding the project, but you have to understand the rest of it if you want our help to be useful.

  10. #10
    PowerPoster
    Join Date
    May 2006
    Location
    Location, location!
    Posts
    2,673

    Re: Winsock Data Arrival issue

    Update: In case no-one responds to this and someone else needs this code too, I've written a quick hex to decimal converter:
    vb Code:
    1. Public Function hextodec(str As String) As Long
    2. Dim vl As Long, n As Long, b As Double
    3. n = 1
    4. For b = Len(str) To 1 Step -1
    5. vl = vl + (Val("&H" & Mid(str, b, 1)) * n)
    6. n = n * 16
    7. Next b
    8. hextodec = vl
    9. End Function
    Well, everyone else has been doing it :-)
    Loading a file into memory QUICKLY - Using SendKeys - HyperLabel - A highly customisable label replacement - Using resource files/DLLs with VB - Adding GZip to your projects
    Expect more to come in future
    If I have helped you, RATE ME! :-)

    I love helping noobs with their VB problems (probably because, as an amateur programmer, I am only slightly better at VB than them :-)) but if you SERIOUSLY want to get help for free from a community such as VBForums, you have to first have a grounding (basic knowledge) in VB6, otherwise you're way too much work to help...You've got to give a little if you want to get help from us, in other words!

    And we DON'T do your homework. If your tutor doesn't teach you enough to help you make the project without his or her help, FIND A BETTER TUTOR or try reading books on programming! We are happy to help with minor things regarding the project, but you have to understand the rest of it if you want our help to be useful.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width