Jump to content
xisto Community
Galahad

Ftp In Visual Basic 6.0 Start making your FTP client using VB6

Recommended Posts

Recently, I had a need to make a FTP client, since our webhosting FTP server was kind of exotic, and very restrictive, and most of uploads, even though they reach 100% would crash... File would be uploaded to a server, but FTP clients just froze upon completion, waiting for the 226 (OK) from FTP server... So, I had to make my own, one who would not wait for 226, but instead, watch the file pload progress...

 

This tutorial is not fuly complete, in the sense that it does not offer COMPLETE FTP client functionality (for example, I ddn't write the code for FTP download, though it is fairly easy to add it, since all the necessary functions are already written)... I was ofcourse guided by the thought that tutorials sould encourage someone to do some further reading and exploration of their own, not just copy/paste...

 

First, let's start off with how FTP works... FTP uses 2 ports to communicate: port 21 for command communication, and some other port for data transmission... So, knowing this, let's begin:

 

First off, we need to declare some variables we'll use in our code:

Option ExplicitDim CData   As String ' We'll use this to store incoming FTP dataDim CResp   As String ' We'll use this to store response from FTP serverDim DataOK  As Boolean ' Is the data sent?Dim CmdOK   As Boolean ' Is the command sent?Dim ATS	 As Single ' Approximate transfer speedDim ATT	 As Single ' Approximate transfer timeDim Data	As String ' We take chunks of data we receive from the server, and merge them in this variableDim p_Log   As Boolean ' Should we log FTP activity?Private Const C_TIMEOUT As Single = 1 ' Default timeout value of 1 secondDim ConnLog As New Collection

OK, next, we'll need several of the controls on the Form:

2x Winsock controls: wskFTPC and wskFTPD

1x Command button: Command1

1x Text box: Text1

1x Timer: Timer1; resolution 100ms

 

OK, that set, let's add some actual FTP code.. Since many of FTP commands will often be called, so to avoid repetition, we'll write several of the functions and subs:

Private Function CSend(ByVal Command As String) As BooleanIf CmdOK Then  CmdOK = False  CSend = False  wskFTPC.SendData Command & vbCrLf  ConnLog.Add "-> " & Command  If p_Log Then	Text1.Text = Text1.Text & ("-> " & Command & vbCrLf)  End If  CSend = WaitCOKEnd IfEnd FunctionPrivate Function DSend(ByVal Data As String) As BooleanIf DataOK Then  DataOK = False  wskFTPD.SendData Data  DSend = WaitOKEnd IfEnd Function

We will call CSend() every time we want to send a command, and DSend() every time we send data chunk to a server. Let's move on... You must have noticed some more of the functions here, so let's write them (and others) too:

 

Public Sub Wait(ByVal ms As Single)Dim t1 As Single, t2 As Singlet1 = TimerWhile t2 < t1 + ms  DoEvents  t2 = TimerWendEnd SubPublic Function GetCode(Optional ByVal Timeout As Single = C_TIMEOUT) As StringDim t1 As Single, t2 As SingleCResp = ""GetCode = ""t1 = TimerWhile CResp = ""  t2 = Timer  If t2 > t1 + Timeout Then Exit Function  DoEventsWendGetCode = CRespEnd FunctionPublic Function WaitCode(ByVal Code As String, Optional ByVal Timeout As Single = C_TIMEOUT) As BooleanDim t1 As Single, t2 As Singlet1 = TimerWaitCode = FalseWhile CResp <> Code  t2 = Timer  If t2 > t1 + Timeout Then Exit Function  DoEventsWendWaitCode = TrueEnd FunctionPublic Function WaitOK(Optional ByVal Timeout As Single = C_TIMEOUT) As BooleanDim t1 As Single, t2 As Singlet1 = TimerWaitOK = FalseWhile DataOK = False  t2 = Timer  If t2 > t1 + Timeout Then Exit Function  DoEventsWendWaitOK = TrueEnd FunctionPublic Function WaitCOK(Optional ByVal Timeout As Single = C_TIMEOUT) As BooleanDim t1 As Single, t2 As Singlet1 = TimerWaitCOK = FalseWhile CmdOK = False  t2 = Timer  If t2 > t1 + Timeout Then Exit Function  DoEventsWendWaitCOK = TrueEnd FunctionPublic Function WaitConn(Optional ByVal Timeout As Single = C_TIMEOUT) As BooleanDim t1 As Single, t2 As Singlet1 = TimerWaitConn = FalseWhile wskFTPD.State <> sckConnected  t2 = Timer  If t2 > t1 + Timeout Then Exit Function  If wskFTPD.State = sckConnecting Then t1 = Timer  DoEventsWendWaitConn = TrueEnd FunctionPrivate Function SendPORT() As BooleanDim pIP   As StringDim pPort As StringDim pH	As LongDim pL	As LongDim lPort As LongRandomize TimerlPort = Int(12000 * Rnd + 6000)SendPORT = FalsepH = lPort \ 256pL = lPort - (pH * 256)pPort = Trim(CStr(pH)) & "," & Trim(CStr(pL))With wskFTPD  .LocalPort = pH * 256 + pL  pIP = .LocalIP  .ListenEnd WithpIP = Replace(pIP, ".", ",")CSend ("PORT " & pIP & "," & pPort)If Not WaitCode("200") Then Exit FunctionSendPORT = TrueEnd FunctionPrivate Function SendLIST(Optional ByVal FilePath As String = "") As BooleanData = ""CSend ("LIST" & IIf((FilePath = ""), "", " " & FilePath))If Not WaitCode("150") Then Exit FunctionWhile wskFTPD.State = sckConnected  DoEvents  Label3.Caption = CRespWendOpen "c:\incoming" For Binary As #120Put #120, 1, DataClose #120Data = ""SendLIST = TrueEnd FunctionPrivate Function SendFile(ByVal FileName As String, Optional ByVal BuffSize As Long = 2048) As BooleanDim hFile As IntegerDim fBuff As StringDim lBuff As LongDim t1	As SingleDim t2	As SingleDim s As Long, i As Long, r As LonghFile = FreeFilelBuff = BuffSizet1 = TimerOpen FileName For Binary As #hFile  If LOF(hFile) >= lBuff Then	s = LOF(hFile) \ lBuff	Picture1.ScaleWidth = s	Label1.Width = 0	fBuff = Space(lBuff)	For i = 1 To s	  Get #hFile, , fBuff	  DSend fBuff	  Label1.Width = i	  DoEvents	Next i	r = LOF(hFile)	r = r - (lBuff * s)	If r > 0 Then	  fBuff = Space(r)	  Get #hFile, , fBuff	  DSend fBuff	End If	Label1.Width = LOF(hFile)  Else	Picture1.ScaleWidth = LOF(hFile)	fBuff = Space(LOF(hFile))	Get #hFile, , fBuff	DSend fBuff	Label1.Width = LOF(hFile)  End If  DoEvents  t2 = Timer  ATS = LOF(hFile) / ((t2 - t1) + 1)  ATT = t2 - t1Close #hFilewskFTPD.CloseSendFile = TrueEnd Function

Okie, now we've written all of the functions we'll need... Next on, we need to add some event handlers:

Private Sub Timer1_Timer()Label2.Caption = wskFTPD.StateIf wskFTPD.State = sckClosing Then wskFTPD.CloseEnd SubPrivate Sub wskFTPC_SendComplete()CmdOK = TrueDoEventsEnd SubPrivate Sub Form_Unload(Cancel As Integer)If wskFTPC.State = 7 Then  Text1.Text = Text1.Text & CSend("QUIT")  wskFTPC.CloseElse  wskFTPC.CloseEnd IfEnd SubPrivate Sub wskFTPD_ConnectionRequest(ByVal requestID As Long)wskFTPD.ClosewskFTPD.Accept requestIDText1.Text = Text1.Text & "*** Data connection established" & vbCrLfEnd SubPrivate Sub wskFTPD_DataArrival(ByVal bytesTotal As Long)Dim s As StringwskFTPD.GetData sData = Data & sEnd SubPrivate Sub wskFTPD_SendComplete()DataOK = TrueDoEventsEnd Sub

OK, that's settled too... We've written basic FTP handling, upload will work, download too, but you'll have to come up with your own download function, that wraps around existing functions :(

 

Now that we've got all the ingredients, let's make a juicy FTP soup:

Private Sub Command1_Click()CmdOK = TrueDataOK = Truep_Log = TruewskFTPC.RemoteHost = "ftphost.com"wskFTPC.RemotePort = 21wskFTPC.ConnectIf Not WaitCode("220") Then Exit SubCSend ("USER username")If Not WaitCode("331") Then Exit SubCSend ("PASS password")If Not WaitCode("230") Then Exit SubCSend ("TYPE I")If Not WaitCode("200") Then Exit SubCSend ("CWD sautpro.com/proba")If Not WaitCode("250") Then Exit SubIf Not SendPORT Then Exit SubCSend ("STOR somefile")If Not WaitCode("200") Then Exit SubIf Not WaitConn Then Exit SubIf Not SendFile("c:\.somefile") Then Exit SubIf Not WaitCode("226", 10) Then  CSend "NOOP"  If Not WaitCode("226", 20) Then Exit SubEnd IfText1.Text = Text1.Text & "*** File transfer complete. (Approx. upload speed " & Format(ATS / 1024, "###,##0.00") & "kb/s, Approx. upload time " & Format(ATT, "#,##0.00") & " seconds)" & vbCrLfText1.Text = Text1.Text & "*** Closing data connection." & vbCrLfCSend ("TYPE A")If Not WaitCode("200") Then Exit SubIf Not SendPORT Then Exit SubSendLISTIf Not WaitCode("226", 5) Then  CSend "NOOP"  If Not WaitCode("226", 10) Then Exit SubEnd IfText1.Text = Text1.Text & "*** Directory LISTing received." & vbCrLfEnd Sub

Now, remember to replace ftphost.com, yourfile, username and password with actual values, or this won't work... So, what are we doing? First, we're initializing variables, set wskFTPC to connect to ftphost.com on port 21 (FTP command port)... Then, we send our login info, and inbetween we wait for appropriate responses... Since I made this for specific purpose, error handling is virtualy non-existent, but it's easy to add to this code. You can find a list of FTP responses on the net...

 

I believe code is rather self-explanatory, but if you have any questions regarding this, I'm at your service, just post here, or drop me a PM...

 

You can play around with the code, optimise buffer size for upload, for download, since I used a value that suited best to my internet connection and FTP server type...

 

This ofcourse is not a complete FTP client, it's only a core functionality of FTP... If you wish to build some sort of full blown FTP client, you'll have to work some more on this code...

 

Oh, and if you do make that FTP client based on this code, I'd like it if you put my name somewhere in the credits <_<

 

Cheers, and I hope you will find this usefull in some way...

Share this post


Link to post
Share on other sites

upload text file

Ftp In Visual Basic 6.0

 

I am currently working on some software and I need this program to upload a small text file to an ftp server. After reading this tutorial, it seems like this would be pretty simple for you to do. I've been looking all over the internet to find help with this, and every time I think I find something, it doesn't work, and the author is no help. Please help!

 

many many many many thanks!!

Ethan

 

-question by Ethan

Share this post


Link to post
Share on other sites

Cant get thething to work (does not wait for anything)

Ftp In Visual Basic 6.0

 

Replying to iGuest

 

 

Al it does is exit sub and sit with state at 0, never changing.

 

I tracew it through and canno see how it can work.

 

The logic I see is send command and weait for response, however to exit sub you can never go back!. No lops till timeout or anything I would expect.

 

Explain please?

 

 

-reply by Martin

Share this post


Link to post
Share on other sites

Webbrowser control vb to connect to ftp.
Ftp In Visual Basic 6.0

I want the webbrowser control to open ftp.
I can connct the ftp using  MYUSER:MYPASS@myhost, but that makes the user and pass visible when browsing the histroy of the browser.

How can I make the control to fill in the password and user automatically without being visible in the url?


Thanks in advance,

Roei.

-reply by roei



Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

Terms of Use | Privacy Policy | Guidelines | We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.