Winsock file transfer - Skewed off data
Winsock file transfer - Skewed off data
Winsock file transfer - Skewed off data
Winsock file transfer - Skewed off data
Winsock file transfer - Skewed off data
Winsock file transfer - Skewed off data Winsock file transfer - Skewed off data Winsock file transfer - Skewed off data Winsock file transfer - Skewed off data Winsock file transfer - Skewed off data Winsock file transfer - Skewed off data Winsock file transfer - Skewed off data Winsock file transfer - Skewed off data
Winsock file transfer - Skewed off data Winsock file transfer - Skewed off data
Winsock file transfer - Skewed off data
Go Back  Xtreme Visual Basic Talk > > > Winsock file transfer - Skewed off data


Reply
 
Thread Tools Display Modes
  #1  
Old 07-14-2010, 04:12 PM
AkselJ AkselJ is offline
Newcomer
 
Join Date: Dec 2009
Location: Norway
Posts: 20
Default Winsock file transfer - Skewed off data


Hey,
I am working on a file transfer system via Winsock, but the code I am using appears to skew off the data, and send more than there is... Here's my code.

Server side, sending file
Code:
Public Sub SendFile(ByVal Index As Long, ByVal FileLoc As String, ByVal FilePath As String, Optional ByVal PacketSize As Long = 1024)
Dim Buffer As clsBuffer
Dim PatchData() As Byte, PatchDataSize As Long
Dim PatchSize As Long, PatchRead As Long
    
    Set Buffer = New clsBuffer
    
    iFileNum = FreeFile ' Get free file number
    Open FileLoc For Binary Access Read As iFileNum ' Open file
    
    PatchDataSize = lngMIN(LOF(iFileNum) - Loc(iFileNum), PacketSize)
    PatchSize = LOF(iFileNum)
    
    ' If file size is smaller than PacketSize, then send the whole file, but not more
    ReDim PatchData(lngMIN(LOF(iFileNum), PacketSize) - 1)
    Get iFileNum, , PatchData() ' Read data
    
    Buffer.WriteInteger SPatch
    Buffer.WriteString FilePath
    Buffer.WriteLong PatchSize
    Buffer.WriteLong PatchDataSize
    Buffer.WriteBytes PatchData()
    
    ' Send the buffer
    Call SendDataTo(Index, Buffer.ToArray)
    
    IsSendingFile = False
    
    Do While Not IsSendingFile And IsConnected(Index)
        If iFileNum <= 0 Then Exit Sub
    
        If Loc(iFileNum) >= LOF(iFileNum) Then ' File complete
            Close iFileNum ' Close file
            ' Set file number to 0, will exit sub.
            iFileNum = 0
            Exit Sub
        End If
        
        IsSendingFile = True
        
        ' If the remaining size in the file is smaller then PacketSize, the read only whatever is left
        PatchDataSize = lngMIN(LOF(iFileNum) - Loc(iFileNum), PacketSize)
        
        ReDim PatchData(PatchDataSize - 1) ' Resize buffer
        Get iFileNum, , PatchData ' Read data
        
        Buffer.WriteInteger SPatch
        Buffer.WriteString FilePath
        Buffer.WriteLong PatchSize
        Buffer.WriteLong PatchDataSize
        Buffer.WriteBytes PatchData()
        
        Call SendDataTo(Index, Buffer.ToArray) ' Send Data
        
        IsSendingFile = False
    Loop
End Sub
Client side, handling file
Code:
Private Sub HandlePatch(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
Dim Buffer As clsBuffer
Dim FilePath As String
Dim iFileNum As Integer
Dim FileSize As Long
Dim DataLenght As Long
Dim DataRead As Long
Dim NewData() As Byte

    Set Buffer = New clsBuffer

    Buffer.WriteBytes Data()

    PatchFileCounter = PatchFileCounter + 1
    iFileNum = FreeFile ' Get free file number
    FilePath = App.Path & Buffer.ReadString ' Get file path from buffer
    FileSize = Buffer.ReadLong ' Get total size of patch
    DataLenght = Buffer.ReadLong ' Get size of data from buffer
    NewData() = Buffer.ReadBytes(DataLenght) ' Get the new data
    DataRead = (1024 * PatchFileCounter) + DataLenght ' Calculate read data

    If DataLenght < 1024 Then ' Last part of the file
        PatchFileCounter = 1
        DataRead = 0
    End If
    
    If DataRead = PatchSize Then ' File complete
        Exit Sub
    End If

    frmAutoPatch.lblFile.Caption = FilePath
    frmAutoPatch.shpFileProgress.Width = DataRead / FileSize * 3000
    frmAutoPatch.lblFileProgress.Caption = DataRead & "/" & FileSize

    ' Make sure frmAutoPatcher is showing
    frmAutoPatch.Visible = True
    ' Make sure frmMainMenu isn't showing
    frmMainMenu.Visible = False

    Open FilePath For Binary As #iFileNum ' Open file
    Seek #iFileNum, DataRead ' Find current location in file
    Put #iFileNum, Seek(iFileNum), NewData() ' Write data to file

    Close iFileNum
End Sub
Reply With Quote
  #2  
Old 07-14-2010, 10:53 PM
Cerian Knight's Avatar
Cerian KnightWinsock file transfer - Skewed off data Cerian Knight is offline
Polymath (in disciplina)

Super Moderator
* Expert *
 
Join Date: May 2004
Location: Michigan
Posts: 4,191
Default

I've only given a quick look at this and find no issues with the server.

I believe the client is incrementing PatchFileCounter without considering if DataLeng[bold]th[/bold] is < 1024. If it is < 1024 then 1024 + PatchFileCounter + DataLength will miscalculate DataRead (later affecting Seek).

But following that line, 'If DataLength < 1024 Then' will force DataRead to 0 on the last (logical) packet which again will cause a problem with Seek.

Now how about a file that is exactly 1024 bytes (no < 1024 issues)? When 'If DataRead = PatchSize' is True, it will Exit Sub without commiting the data, it seems. I'm not seeing where the client Dim or read of PatchSize is done? If the server sends it, the client needs to ReadLong it in order.

If I'm not making sense here, let me know. My experience with WinSock is mostly in the creation of 'air' code for customers trying to create LIMS-like client software to process our server data.
__________________
I got all the answers wrong on the GLAT, apparently even #9 (where I put a period in the middle of the box and labeled it 'singularity ripe for rapid inflation').
Reply With Quote
  #3  
Old 07-16-2010, 05:12 PM
AkselJ AkselJ is offline
Newcomer
 
Join Date: Dec 2009
Location: Norway
Posts: 20
Default

Yeah, I'd managed to trace the problem to the client, the server does send the right amount of packets so I was assuming it would have to be the client's saving. Oh, and PatchSize was changed to FileSize, I just forgot to change it there. It was fixed just after I posted this. Oh and the 1024 byte file problem, yeah. I'm taking a chance I'll never have to send a file of that size. xD Though now that I think about it, I could just check if the FileSize = 1024.

Well. Your post really enlightened me, and I found out more problems and their solutions after fixing what you mentioned.

Here's my new client side handling:

Code:
Private Sub HandlePatch(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
Dim Buffer As clsBuffer
Dim FilePath As String
Dim iFileNum As Integer
Dim FileSize As Long
Dim DataLenght As Long
Dim DataRead As Long
Dim NewData() As Byte

    Set Buffer = New clsBuffer

    Buffer.WriteBytes Data()

    iFileNum = FreeFile ' Get free file number
    FilePath = App.Path & Buffer.ReadString ' Get file path from buffer
    FileSize = Buffer.ReadLong ' Get total size of patch
    DataLenght = Buffer.ReadLong ' Get size of data from buffer
    NewData() = Buffer.ReadBytes(DataLenght) ' Get the new data
    
    ' Make sure PatchFileCounter isn't 0
    If PatchFileCounter = 0 Then PatchFileCounter = 1
    
    If DataLenght < CHUNK Then ' Last part of the file
        If FileSize > CHUNK Then
            DataRead = CHUNK * PatchFileCounter '+ DataLenght ' Set DataRead
            PatchFileCounter = 1 ' Reset counter
        Else
            ' Check if we need to delete file
            If FileExist(Right(FilePath, Len(FilePath) - Len(App.Path))) Then
                Kill FilePath ' Delete file
            End If
            
            ' Set DataRead to DataLenght, as this file's size <= CHUNK
            DataRead = DataLenght
        End If
        
        PatchFileCounter = 1 ' Reset counter
    Else
        ' Check if we need to delete file
        If PatchFileCounter = 1 And FileExist(Right(FilePath, Len(FilePath) - Len(App.Path))) Then
            Kill FilePath ' Delete file
        End If
        
        DataRead = CHUNK * PatchFileCounter ' Calculate read data
        PatchFileCounter = PatchFileCounter + 1 ' Increase counter
    End If
    
    ' Make sure frmAutoPatcher is showing
    frmAutoPatch.Visible = True
    ' Make sure frmMainMenu isn't showing
    frmMainMenu.Visible = False

    Open FilePath For Binary As #iFileNum ' Open file
    Seek #iFileNum, DataRead - DataLenght + 1 ' Find current location in file
    Put #iFileNum, Seek(iFileNum), NewData() ' Write data to fil
    Close iFileNum ' Close file
    
    ' Update frmAutoPatch
    frmAutoPatch.lblFile.Caption = FilePath
    frmAutoPatch.shpFileProgress.Width = DataRead / FileSize * 3000
    frmAutoPatch.lblFileProgress.Caption = DataRead & "/" & FileSize
End Sub
Works like a charm for files <= 1024 B, but when they're more, it writes the same 1024 bytes as many times as there are packets...
It seems like the client reads DataLenght as 1024 each time, and also reads the same data as new data each time. Strange, because the server doesn't send the same. I've tested this.

Any ideas on this?

Last edited by AkselJ; 07-16-2010 at 05:25 PM.
Reply With Quote
  #4  
Old 07-16-2010, 09:18 PM
Cerian Knight's Avatar
Cerian KnightWinsock file transfer - Skewed off data Cerian Knight is offline
Polymath (in disciplina)

Super Moderator
* Expert *
 
Join Date: May 2004
Location: Michigan
Posts: 4,191
Arrow

I noticed that the server is sending SPatch, but the client is not reading it from the buffer. I corrected that, issues with filesize being a multiple of 1024 and some DataRead math, plus I simplified the logic and removed some redundancy. See what you think (since I've only been running your code in my head):
Code:
Private Sub HandlePatch(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
Dim Buffer As clsBuffer
Dim FilePath As String
Dim iFileNum As Integer
Dim FileSize As Long
Dim DataLenght As Long
Dim DataRead As Long
Dim NewData() As Byte
    Set Buffer = New clsBuffer
    Buffer.WriteBytes Data()
    iFileNum = FreeFile ' Get free file number
    FilePath = App.Path & Buffer.ReadString ' Get file path from buffer
    FileSize = Buffer.ReadLong ' Get total size of patch
    DataLenght = Buffer.ReadLong ' Get size of data from buffer
    NewData() = Buffer.ReadBytes(DataLenght) ' Get the new data
    ' Make sure PatchFileCounter isn't 0
    If PatchFileCounter = 0 Then 'New file or last file committed
        PatchFileCounter = 1
        ' Check if we need to delete file
        If FileExist(Right(FilePath, Len(FilePath) - Len(App.Path))) Then
            Kill FilePath ' Delete file
        End If
    End If
    If DataLenght < Chunk Or FileSize = Chunk Then ' Last part of the file
        If FileSize > Chunk Then
            DataRead = Chunk * (PatchFileCounter - 1) + DataLenght ' Set DataRead
        Else
            ' Set DataRead to DataLenght, as this file's size <= CHUNK
            DataRead = DataLenght
        End If
    Else
        DataRead = Chunk * PatchFileCounter ' Calculate read data
        PatchFileCounter = PatchFileCounter + 1 ' Increase counter
    End If
    If DataRead = FileSize Then PatchFileCounter = 0         ' Reset counter
    ' Make sure frmAutoPatcher is showing
    frmAutoPatch.Visible = True
    ' Make sure frmMainMenu isn't showing
    frmMainMenu.Visible = False
    Open FilePath For Binary As #iFileNum ' Open file
    Seek #iFileNum, DataRead - DataLenght + 1 ' Find current location in file
    Put #iFileNum, , NewData() ' Write data to fil
    Close iFileNum ' Close file
    ' Update frmAutoPatch
    frmAutoPatch.lblFile.Caption = FilePath
    frmAutoPatch.shpFileProgress.Width = DataRead / FileSize * 3000
    frmAutoPatch.lblFileProgress.Caption = DataRead & "/" & FileSize
End Sub
__________________
I got all the answers wrong on the GLAT, apparently even #9 (where I put a period in the middle of the box and labeled it 'singularity ripe for rapid inflation').

Last edited by Cerian Knight; 07-17-2010 at 09:49 AM. Reason: removed SPatch and fixed Kill file
Reply With Quote
  #5  
Old 07-17-2010, 05:39 AM
AkselJ AkselJ is offline
Newcomer
 
Join Date: Dec 2009
Location: Norway
Posts: 20
Default

Sorry, I must've forgotten to explain how the buffers are handled.
The buffers use enumerated headers. Buffers from client start with C, and buffers from the server start with S. Then, when either the server or client receives data, it reads the first integer, and then sends it to the specified sub, as each enumeration is addressed to a sub.
Get it? So there's no need to read it from the buffer.

Anyways, I tried what you gave me. It's better, but still repeats the same data.. But thanks anyways. I do appreciate your help.
Reply With Quote
  #6  
Old 07-17-2010, 09:58 AM
Cerian Knight's Avatar
Cerian KnightWinsock file transfer - Skewed off data Cerian Knight is offline
Polymath (in disciplina)

Super Moderator
* Expert *
 
Join Date: May 2004
Location: Michigan
Posts: 4,191
Default

I removed SPatch and fixed the Kill file code in my previous post. If that doesn't help, you'll need to slowly send the packets one-by-one and look at Data() and NewData() to make sure clsBuffer isn't mangling something on the client side.
__________________
I got all the answers wrong on the GLAT, apparently even #9 (where I put a period in the middle of the box and labeled it 'singularity ripe for rapid inflation').
Reply With Quote
  #7  
Old 07-19-2010, 08:23 AM
AkselJ AkselJ is offline
Newcomer
 
Join Date: Dec 2009
Location: Norway
Posts: 20
Default

It actually seems like clsBuffer is mangling something. When testing, server sends three different sets of data in the buffer, while the client receives the first one three times. Hmph.

I've had these kinds of errors before, actually. But it usually turns out to be something else.
Reply With Quote
  #8  
Old 07-19-2010, 11:28 AM
Cerian Knight's Avatar
Cerian KnightWinsock file transfer - Skewed off data Cerian Knight is offline
Polymath (in disciplina)

Super Moderator
* Expert *
 
Join Date: May 2004
Location: Michigan
Posts: 4,191
Default

You're welcome to attach clsBuffer (or better yet test C/S projects that demonstrate the problem... no EXE/DLL/OCX files).
__________________
I got all the answers wrong on the GLAT, apparently even #9 (where I put a period in the middle of the box and labeled it 'singularity ripe for rapid inflation').
Reply With Quote
  #9  
Old 07-19-2010, 02:07 PM
AkselJ AkselJ is offline
Newcomer
 
Join Date: Dec 2009
Location: Norway
Posts: 20
Default

Attached clsBuffer.

Thanks a tonne. Your help means a lot to me. If this is fixed, I can finally send the game client out to my developers.
Attached Files
File Type: cls clsBuffer.cls (4.7 KB, 15 views)
Reply With Quote
  #10  
Old 07-21-2010, 12:27 AM
Cerian Knight's Avatar
Cerian KnightWinsock file transfer - Skewed off data Cerian Knight is offline
Polymath (in disciplina)

Super Moderator
* Expert *
 
Join Date: May 2004
Location: Michigan
Posts: 4,191
Default

The repeated data is because after use of Buffer.ToArray in the server, you are not doing a Buffer.Flush. So the next time the call is made it sends the whole buffer again.

Also, I had a few issues with your FilePath and FileExists concatenations:

App.Path has no trailing backslash if it contains a folder name (e.g., 'C:\Temp'), but if it is root it has one (e.g., 'C:\'). You must take this into account before appending the filename.

Even then, you had better double-check that the old file is actually being deleted... because if not, a larger file will not be size-adjusted downward when it is replaced by a smaller one of the same name.

Fix those items, and it should be fine.
__________________
I got all the answers wrong on the GLAT, apparently even #9 (where I put a period in the middle of the box and labeled it 'singularity ripe for rapid inflation').
Reply With Quote
  #11  
Old 07-21-2010, 06:08 PM
AkselJ AkselJ is offline
Newcomer
 
Join Date: Dec 2009
Location: Norway
Posts: 20
Default

Works now, everything should be fixed now. Thanks!
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Winsock file transfer - Skewed off data
Winsock file transfer - Skewed off data
Winsock file transfer - Skewed off data Winsock file transfer - Skewed off data
Winsock file transfer - Skewed off data
Winsock file transfer - Skewed off data
Winsock file transfer - Skewed off data Winsock file transfer - Skewed off data Winsock file transfer - Skewed off data Winsock file transfer - Skewed off data Winsock file transfer - Skewed off data Winsock file transfer - Skewed off data Winsock file transfer - Skewed off data
Winsock file transfer - Skewed off data
Winsock file transfer - Skewed off data
 
Winsock file transfer - Skewed off data
Winsock file transfer - Skewed off data
 
-->