Results 1 to 12 of 12

Thread: Data truncation when using Winsock GetData?

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Mar 2001
    Posts
    152

    Data truncation when using Winsock GetData?

    I am using Winsock GetData and it appears that the data being returned is getting truncated. The data is a string and it will appear truncated in the middle of a word or sentence. It seems very simple:

    VB Code:
    1. Dim strData As String
    2. wSockUDP.GetData strData, vbString

    Any ideas??

    Thanks.

  2. #2
    Addicted Member señorbadger's Avatar
    Join Date
    Oct 2003
    Location
    Mud pools of wellingborough
    Posts
    193
    i dont know if this will help but i just use

    VB Code:
    1. Dim strData As String
    2. wSockUDP.GetData strData

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Mar 2001
    Posts
    152
    It doesn't seem to make a difference. Is there a certain length that a string can be in general? I can't imagine I am hitting it, but it would explain it. Is there another data type that can be used?

    Thanks.

  4. #4
    Addicted Member señorbadger's Avatar
    Join Date
    Oct 2003
    Location
    Mud pools of wellingborough
    Posts
    193
    variants, i dont like to use them but worth a try ??

    eg

    VB Code:
    1. Dim strData As variant
    2. wSockUDP.GetData strData

  5. #5
    PowerPoster
    Join Date
    Nov 2002
    Location
    Manila
    Posts
    7,629
    If the data is large, yes it will be chopped up into multiple sends, hence multiple data arrivals, hence your problem.

    At the data arrival side, concatenate getdata for the data arrivals until the entire length has been downloaded. To determine if you've received the entire length; send additional header info (total data length in bytes) at the start of send or send special string on send complete or some other implementation.

  6. #6

    Thread Starter
    Addicted Member
    Join Date
    Mar 2001
    Posts
    152
    Whoa, that like blew over my head...

    Basically I do a SendData and then GetData the response over UDP. I have no idea the length of the response from the server and I will not necessarily know if it is chopped off until I am done processing it.

    I am new to Winsock and if there is anyway you could give me a sample of what you are talkling about that would be appreciated.

    Thanks for your help.

  7. #7
    Frenzied Member
    Join Date
    Aug 2000
    Location
    O!
    Posts
    1,177
    I have to agree with leinad31.

    At my company, we use a 52 byte header on all of our records that are sent via socket connections. I use the header in all of my C, VB and Java sockets apps.

    Among other things, the header contains a long whose value is the sum of the header length and record length. One of my VB apps gets a record from a C server on another platform that is over 18,500 bytes long. As I recall, when I debugging my code, the record came back in blocks of 1460 bytes followed by one smaller block and I had to append the blocks until I had received everything.

    Here is the DataArrival routine from that app. Hopefully, it will give you some idea of what we are saying.
    VB Code:
    1. Private Sub tcpClient_DataArrival(ByVal bytesTotal As Long)
    2.    ' determine the data type and process it
    3.    
    4.    ' get the buffer contents
    5.    ReDim gbIOBuff(bytesTotal)
    6.    tcpClient.GetData gbIOBuff, vbArray + vbByte, bytesTotal
    7.    
    8.    If copyPtr = 0 Then ' we are at the beginning of a new reply
    9.       ' save size & type of reply
    10.       CopyMemory recLen, gbIOBuff(0), 4     ' get the record length
    11.       recLen = ntohl(recLen)                ' convert to little-endian
    12.       CopyMemory codeCheck, gbIOBuff(52), 2 ' get the reply type
    13.       codeCheck = ntohs(codeCheck)          ' conver to little-endian
    14.       ReDim gbReplyBuff(bytesTotal)         ' clear old data record & start new one
    15.    Else
    16.       ReDim Preserve gbReplyBuff(copyPtr + bytesTotal) ' retain data & bump the size
    17.    End If
    18.      
    19.    ' copy the received data to the work buffer at location referenced by copyptr
    20.    CopyMemory gbReplyBuff(copyPtr), gbIOBuff(0), bytesTotal
    21.    If UBound(gbReplyBuff) = recLen Then
    22.       ' we got the entire file
    23.       If recLen = gilocLen Or recLen = gijobLen Or recLen = giSockRtn Then
    24.          If codeCheck = glLocRequest Then
    25.             Process_Locations        ' called 1 time only at Form_Load
    26.          Else
    27.             If codeCheck = glJobRequest Then
    28.                Process_JobStats      ' called for each chart request
    29.             Else
    30.                Beep
    31.                sbStatus.Panels(2).Text = "Error: " & codeCheck & ", No data returned"
    32.                intTics = 0 ' reset display timer
    33.             End If
    34.          End If
    35.       End If
    36.       copyPtr = 0   ' reset the flag\pointer
    37.    Else
    38.       ' save the current record length\next copy location
    39.       copyPtr = UBound(gbReplyBuff)
    40.    End If
    41.      
    42. End Sub

  8. #8
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106
    UDP will chop packets up, but the size of the packet is determined by the network (sort of). Therefore, don't rely on any particular packet size. Sizes can get down to below 512 Bytes, which really isn't much.

    Furthermore, UDP doesn't guarantee that any particular packet makes it. Therefore, if you suspect that the data is going to exceed the packet size, you will need to have some mechanism to be sure that you can know whether you have all the data, and a means to re-submit for the missing data.

    A header that tells you the total number of bytes helps, since you can determine whether or not you got the whole thing, but it doesn't tell you much about what was lost if something goes away. Solving that isn't all that easy, since you may not know how big the packet size will be. For that reason, UDP is generally used for REALLY small packet situations.

    One possibility for larger packets would be to chop each message into very small pieces, number each piece, and send them. The header would include the number of pieces. There fore, the receiveing end can determine which piece is missing (by the number), the number of total packets, and the order of the packets.

  9. #9
    PowerPoster
    Join Date
    Nov 2002
    Location
    Manila
    Posts
    7,629
    If your concerned about chunks not reaching the destination then use TCP sockets instead.

  10. #10
    Super Moderator Wokawidget's Avatar
    Join Date
    Nov 2001
    Location
    Headingly Occupation: Classified
    Posts
    9,632
    Here's a nice DLL, source code, that replaces the winsock control.
    This uses 2 classes...the cSocket class, that is a direct replacement for the winsock control, and my own class, Socket, which is a wrapper class for the cSocket class.
    This wrapper class deals with large amounts of data, and removes the hassel of joining packets together.

    There is a very basic small client server test app in the zip file also.

    Hope this is of use...

    If you have any questions then give me a shout.

    Woka

  11. #11

    Thread Starter
    Addicted Member
    Join Date
    Mar 2001
    Posts
    152
    Was there a file with this? Did I miss a link? Thanks for the help!

  12. #12

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