Solved

Winsock - File Transfer

Posted on 2003-11-08
12
501 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
12 Comments
 
LVL 48

Accepted Solution

by:
AlexFM earned 48 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
 
LVL 85

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 47 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
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 

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 85

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 85

Expert Comment

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

Expert Comment

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

Idle_Mind
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

When we want to run, execute or repeat a statement multiple times, a loop is necessary. This article covers the two types of loops in Python: the while loop and the for loop.
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

708 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now