Winsock - File Transfer

I'm wondering, wats the easiest way to transfer files over the internet/network. I'm guessing winsock.. and how would i do it...?

Is there anything else that would be easier, if so how?

BJA
ChrisAnnableAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ChrisAnnableAuthor Commented:
Thankyou, thats wat i need, only help I need is 2 know how it works :P

This sub here is about the only part i don't understand:

Private Sub SendFile()
    Dim BufFile As String
    Dim LnFile As Long
    Dim nLoop As Long
    Dim nRemain As Long
    Dim Cn As Long
   
    On Error GoTo GLocal:
    LnFile = FileLen(SrcPath)
    If LnFile > 8192 Then
        nLoop = Fix(LnFile / 8192)
       
        nRemain = LnFile Mod 8192
    Else
        nLoop = 0
        nRemain = LnFile
    End If
   
    If LnFile = 0 Then
        MsgBox "Ivalid Source File", vbCritical, "Client Message"
        Exit Sub
    End If
   
    Open SrcPath For Binary As #1
    If nLoop > 0 Then
        For Cn = 1 To nLoop
            BufFile = String(8192, " ")
            Get #1, , BufFile
            WskClient.SendData BufFile
            IsReceived = False
            lbByteSend.Caption = "Bytes Sent: " & Cn * 81092 & " Of " & LnFile
            lbByteSend.Refresh
            While IsReceived = False
                DoEvents
            Wend
        Next
        If nRemain > 0 Then
            BufFile = String(nRemain, " ")
            Get #1, , BufFile
            WskClient.SendData BufFile
            IsReceived = False
            lbByteSend.Caption = "Bytes Sent: " & LnFile & " Of " & LnFile
            lbByteSend.Refresh
            While IsReceived = False
                DoEvents
            Wend
        End If
    Else
        BufFile = String(nRemain, " ")
        Get #1, , BufFile
        WskClient.SendData BufFile
        IsReceived = False
        While IsReceived = False
            DoEvents
        Wend
    End If
    WskClient.SendData "Msg_Eof_"    'end of file tag
    Close #1
    Exit Sub
GLocal:
    MsgBox Err.Description
   
End Sub

Could somebody put coments on each line or explain wat it does?
0
ChrisAnnableAuthor Commented:
and this: :P

Private Sub WskServer_DataArrival(Index As Integer, ByVal bytesTotal As Long)
    Dim RecBuffer As String
    Dim Ret As Integer
   
    On Error GoTo GLocal
   
    WskServer(Index).GetData RecBuffer
    Select Case Left(RecBuffer, 8)
        Case "Msg_Eof_"
            Close #FL
            lblInfo.Caption = "File Received..."
        Case "Msg_Dst_"
            DstPath = Right(RecBuffer, Len(RecBuffer) - 8)
               
            FL = FreeFile
            'overwrite file
            On Error Resume Next
            If Len(Dir(DstPath)) > 0 Then
                Ret = MsgBox("File Already Exist!!!" & vbCrLf & " You Wont Overwrite It??", vbQuestion + vbYesNo, "TFTServer Message")
                If Ret = vbYes Then
                    Kill DstPath
                Else
                    'insert code to notify the error
                    'to client
                    Unload Me
                End If
            End If
            Open DstPath For Binary As #FL
            lbFilereceived.Caption = DstPath
            WskServer(Index).SendData "Msg_OkS"
       
        Case Else
            BytesRec = BytesRec + Len(RecBuffer)
            Put #FL, , RecBuffer
            lbBytesReceived.Caption = "Bytes received: " & BytesRec
            WskServer(Index).SendData "Msg_Rec"
    End Select
   
    Exit Sub
GLocal:
    MsgBox Err.Description
    Unload Me
   
End Sub
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

Mike TomlinsonMiddle School Assistant TeacherCommented:
I'll do the first part for you.  The App sends the file in 8192 byte chunks.  This is an arbitrary number.  Make it to big and your TCP packets will probably get split by a server down the line on along the way.  Make it too small and you won't send as fast as you possibly could.  I'm sure you could start a heated debate about the optimum chunk size to send files if you so desire to further explore this number. =)

I will mention one glaring defecieny in this Client/Server app that could be fixed with little effort.  The Server assumes that if the  destination file is there, then you want to overwrite it, otherwise it pukes.  By making the client send the file size along with the destination name, you could easily determine if the dest size is smaller than the source size and ask the client if it wants to resume the download instead of overwriting.  If so, then open the source file in binary and move the file pointer to the correct position using the Seek() function.  Then do your chunk/remainder calcuations like usual using the remaining file size to be sent and send the file.  The client/server would have to send a couple more messages back and forth to tell each other the respective file sizes.  If resuming, then on the server side simply open file for Append and add the chunks on.  Voila!...you now have resumable send capability.  

Also, (I lied, I'll mention two defiencies) the server is asking the question as to whether or not file overwrite is to occur.  This will cause the client to just sit there stupidly waiting for someone at the server to close the msgbox on the other side.  During development this is fine because the client/server are on the same machine but in reality the server is usually somewhere else.  In my opinion, the file sender should make the decision as to whether or not to resume or overwrite.  If security is an issue then the Server should make people log in like an FTP server before accepting the client request to connect.

Anyhoo, I do ramble on... =)
Without further adieu, for what they are worth, here are my comments in the code:

Private Sub SendFile()
    Dim BufFile As String  ' Buffer to hold current chunk of file to send
    Dim LnFile As Long ' Length in bytes of file being sent
    Dim nLoop As Long ' number of whole chunks we are sending
    Dim nRemain As Long ' size of remaining chunk...if there is one
    Dim Cn As Long ' current chunk number we are sending
   
    On Error GoTo GLocal: ' pop up msgbox if something goes wrong
    LnFile = FileLen(SrcPath) ' grab lengh of file in bytes
    If LnFile > 8192 Then ' is file greater than 8192 bytes?
        nLoop = Fix(LnFile / 8192) ' how many 8192 byte chunks are in the file?
                   
        nRemain = LnFile Mod 8192 ' how big is the remainder?
    Else
        nLoop = 0 ' file smaller then 8192 bytes
        nRemain = LnFile ' just sending the whole file in one chunk as the remainder
    End If
   
    If LnFile = 0 Then ' won't send a 0 byte file
        ' Personally, I would send a 0k file, it may be being used as a flag of some
        ' sort to some other application.  All you have to do is open and then close
        ' the file on the other end and you have 0k file.
        MsgBox "Ivalid Source File", vbCritical, "Client Message"
        Exit Sub
    End If
   
    Open SrcPath For Binary As #1 ' open the file to send in binary mode
    If nLoop > 0 Then ' if file is bigger than 8192 bytes, start sending...
        For Cn = 1 To nLoop ' this loop sends the whole chunks
            BufFile = String(8192, " ") ' create a string buffer 8192 bytes long
            Get #1, , BufFile ' read in next chunk (8192 bytes) of file
            WskClient.SendData BufFile ' send that puppy to the sever
            IsReceived = False ' reset received flag
            ' update our progress on the form
            lbByteSend.Caption = "Bytes Sent: " & Cn * 81092 & " Of " & LnFile
            lbByteSend.Refresh
            ' wait for the server to respond back that it has received the chunk
            ' and written it to the dest file
            ' We will receive back a "Msg_Rec" message in WskClient_DataArrival()
            ' from the server when it is done receiving chunk
            ' this type of loop usually results in CPU usage ramping to 100%
            ' but the app and system will still remain responsive due to DoEvents
            ' There is no elegant way to get around this unless you want to use external
            ' DLL's to implement some kind of multithreading =(
            While IsReceived = False
                DoEvents
            Wend
        Next
        If nRemain > 0 Then ' this part sends any remainder
            ' you can probably figure out this part from the part above
            BufFile = String(nRemain, " ")
            Get #1, , BufFile
            WskClient.SendData BufFile
            IsReceived = False
            lbByteSend.Caption = "Bytes Sent: " & LnFile & " Of " & LnFile
            lbByteSend.Refresh
            While IsReceived = False
                DoEvents
            Wend
        End If
    Else
        ' file was less than 8192 bytes so we are sending the whole thing at once
        BufFile = String(nRemain, " ")
        Get #1, , BufFile
        WskClient.SendData BufFile
        IsReceived = False
        While IsReceived = False
            DoEvents
        Wend
    End If
    ' tell the server we have sent the whole file
    WskClient.SendData "Msg_Eof_"    'end of file tag
    Close #1 ' close the file we are sending
    Exit Sub
GLocal:
    MsgBox Err.Description
   
End Sub
0
deathman5Commented:
http://www.winsockvb.com/article.php?article_id=37
check it out, it is easier to understand if u downloaded the example and saw it :)
0
ChrisAnnableAuthor Commented:
i sorta understand now....

the String() function i don't understand how that works

is there a simplier way of transfering data in Visual Basic???
0
Mike TomlinsonMiddle School Assistant TeacherCommented:
The String() function simply returns a string of the specified length, containing the specified character.

dim x As String
x = String(8, "*")

Now x contains "********".

x = String(8192, " ")

Now x contains 8,192 spaces.

This is the basic algorithm you use to transfer files in VB with the Winsock control.  If you want something easier, use a third party program or ocx.

Idle_Mind
0
Mike TomlinsonMiddle School Assistant TeacherCommented:
Did you ever get your code to work and/or understand it?
0
Mike TomlinsonMiddle School Assistant TeacherCommented:
I recommend the points be split between AlexFM and myself.

Idle_Mind
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Programming Languages-Other

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.