?
Solved

Winsock - File Transfer

Posted on 2003-11-08
12
Medium Priority
?
543 Views
Last Modified: 2013-11-13
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
0
Comment
Question by:ChrisAnnable
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
12 Comments
 
LVL 48

Accepted Solution

by:
AlexFM earned 192 total points
ID: 9706349
0
 

Author Comment

by:ChrisAnnable
ID: 9706490
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
 

Author Comment

by:ChrisAnnable
ID: 9706497
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 86

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 188 total points
ID: 9707023
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
 

Expert Comment

by:deathman5
ID: 9707283
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
 

Author Comment

by:ChrisAnnable
ID: 9745683
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
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 9747972
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
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 9872468
Did you ever get your code to work and/or understand it?
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 10164716
I recommend the points be split between AlexFM and myself.

Idle_Mind
0

Featured Post

[Webinar] Lessons on Recovering from Petya

Skyport is working hard to help customers recover from recent attacks, like the Petya worm. This work has brought to light some important lessons. New malware attacks like this can take down your entire environment. Learn from others mistakes on how to prevent Petya like worms.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
Suggested Courses

765 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question