|
|
|
|
![]() ![]() |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Group: [HOSTED]
Posts: 590 Joined: 4-November 04 From: Novi Sad, Vojvodina Member No.: 2,127 myCENT:48.25 |
Post
#1
Mar 7 2008, 09:47 AM
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: CODE Option Explicit Dim CData As String ' We'll use this to store incoming FTP data Dim CResp As String ' We'll use this to store response from FTP server Dim DataOK As Boolean ' Is the data sent? Dim CmdOK As Boolean ' Is the command sent? Dim ATS As Single ' Approximate transfer speed Dim ATT As Single ' Approximate transfer time Dim Data As String ' We take chunks of data we receive from the server, and merge them in this variable Dim p_Log As Boolean ' Should we log FTP activity? Private Const C_TIMEOUT As Single = 1 ' Default timeout value of 1 second Dim 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: CODE Private Function CSend(ByVal Command As String) As Boolean If 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 = WaitCOK End If End Function Private Function DSend(ByVal Data As String) As Boolean If DataOK Then DataOK = False wskFTPD.SendData Data DSend = WaitOK End If End 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: CODE Public Sub Wait(ByVal ms As Single) Dim t1 As Single, t2 As Single t1 = Timer While t2 < t1 + ms DoEvents t2 = Timer Wend End Sub Public Function GetCode(Optional ByVal Timeout As Single = C_TIMEOUT) As String Dim t1 As Single, t2 As Single CResp = "" GetCode = "" t1 = Timer While CResp = "" t2 = Timer If t2 > t1 + Timeout Then Exit Function DoEvents Wend GetCode = CResp End Function Public Function WaitCode(ByVal Code As String, Optional ByVal Timeout As Single = C_TIMEOUT) As Boolean Dim t1 As Single, t2 As Single t1 = Timer WaitCode = False While CResp <> Code t2 = Timer If t2 > t1 + Timeout Then Exit Function DoEvents Wend WaitCode = True End Function Public Function WaitOK(Optional ByVal Timeout As Single = C_TIMEOUT) As Boolean Dim t1 As Single, t2 As Single t1 = Timer WaitOK = False While DataOK = False t2 = Timer If t2 > t1 + Timeout Then Exit Function DoEvents Wend WaitOK = True End Function Public Function WaitCOK(Optional ByVal Timeout As Single = C_TIMEOUT) As Boolean Dim t1 As Single, t2 As Single t1 = Timer WaitCOK = False While CmdOK = False t2 = Timer If t2 > t1 + Timeout Then Exit Function DoEvents Wend WaitCOK = True End Function Public Function WaitConn(Optional ByVal Timeout As Single = C_TIMEOUT) As Boolean Dim t1 As Single, t2 As Single t1 = Timer WaitConn = False While wskFTPD.State <> sckConnected t2 = Timer If t2 > t1 + Timeout Then Exit Function If wskFTPD.State = sckConnecting Then t1 = Timer DoEvents Wend WaitConn = True End Function Private Function SendPORT() As Boolean Dim pIP As String Dim pPort As String Dim pH As Long Dim pL As Long Dim lPort As Long Randomize Timer lPort = Int(12000 * Rnd + 6000) SendPORT = False pH = lPort \ 256 pL = lPort - (pH * 256) pPort = Trim(CStr(pH)) & "," & Trim(CStr(pL)) With wskFTPD .LocalPort = pH * 256 + pL pIP = .LocalIP .Listen End With pIP = Replace(pIP, ".", ",") CSend ("PORT " & pIP & "," & pPort) If Not WaitCode("200") Then Exit Function SendPORT = True End Function Private Function SendLIST(Optional ByVal FilePath As String = "") As Boolean Data = "" CSend ("LIST" & IIf((FilePath = ""), "", " " & FilePath)) If Not WaitCode("150") Then Exit Function While wskFTPD.State = sckConnected DoEvents Label3.Caption = CResp Wend Open "c:\incoming" For Binary As #120 Put #120, 1, Data Close #120 Data = "" SendLIST = True End Function Private Function SendFile(ByVal FileName As String, Optional ByVal BuffSize As Long = 2048) As Boolean Dim hFile As Integer Dim fBuff As String Dim lBuff As Long Dim t1 As Single Dim t2 As Single Dim s As Long, i As Long, r As Long hFile = FreeFile lBuff = BuffSize t1 = Timer Open 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 - t1 Close #hFile wskFTPD.Close SendFile = True End Function Okie, now we've written all of the functions we'll need... Next on, we need to add some event handlers: CODE Private Sub Timer1_Timer() Label2.Caption = wskFTPD.State If wskFTPD.State = sckClosing Then wskFTPD.Close End Sub Private Sub wskFTPC_SendComplete() CmdOK = True DoEvents End Sub Private Sub Form_Unload(Cancel As Integer) If wskFTPC.State = 7 Then Text1.Text = Text1.Text & CSend("QUIT") wskFTPC.Close Else wskFTPC.Close End If End Sub Private Sub wskFTPD_ConnectionRequest(ByVal requestID As Long) wskFTPD.Close wskFTPD.Accept requestID Text1.Text = Text1.Text & "*** Data connection established" & vbCrLf End Sub Private Sub wskFTPD_DataArrival(ByVal bytesTotal As Long) Dim s As String wskFTPD.GetData s Data = Data & s End Sub Private Sub wskFTPD_SendComplete() DataOK = True DoEvents End 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: CODE Private Sub Command1_Click() CmdOK = True DataOK = True p_Log = True wskFTPC.RemoteHost = "ftphost.com" wskFTPC.RemotePort = 21 wskFTPC.Connect If Not WaitCode("220") Then Exit Sub CSend ("USER username") If Not WaitCode("331") Then Exit Sub CSend ("PASS password") If Not WaitCode("230") Then Exit Sub CSend ("TYPE I") If Not WaitCode("200") Then Exit Sub CSend ("CWD sautpro.com/proba") If Not WaitCode("250") Then Exit Sub If Not SendPORT Then Exit Sub CSend ("STOR somefile") If Not WaitCode("200") Then Exit Sub If Not WaitConn Then Exit Sub If Not SendFile("c:\.somefile") Then Exit Sub If Not WaitCode("226", 10) Then CSend "NOOP" If Not WaitCode("226", 20) Then Exit Sub End If Text1.Text = Text1.Text & "*** File transfer complete. (Approx. upload speed " & Format(ATS / 1024, "###,##0.00") & "kb/s, Approx. upload time " & Format(ATT, "#,##0.00") & " seconds)" & vbCrLf Text1.Text = Text1.Text & "*** Closing data connection." & vbCrLf CSend ("TYPE A") If Not WaitCode("200") Then Exit Sub If Not SendPORT Then Exit Sub SendLIST If Not WaitCode("226", 5) Then CSend "NOOP" If Not WaitCode("226", 10) Then Exit Sub End If Text1.Text = Text1.Text & "*** Directory LISTing received." & vbCrLf End 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... |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Group: Members
Posts: 5,876 Joined: 21-September 07 Member No.: 50,369 |
Post
#2
Jul 18 2008, 06:22 AM
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 |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Group: Members
Posts: 5,876 Joined: 21-September 07 Member No.: 50,369 |
Post
#3
Oct 14 2008, 03:30 PM
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 |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Group: Members
Posts: 5,876 Joined: 21-September 07 Member No.: 50,369 |
Post
#4
Nov 10 2008, 07:56 AM
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 ftp://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 |
![]() ![]() |
Similar Topics
| Topic Title | Replies | Topic Starter | Views | Last Action | |||
|---|---|---|---|---|---|---|---|
![]() |
20 | Shackman | 36,298 | 16th December 2008 - 08:10 AM Last post by: mahesh2k |
|||
![]() |
0 | Jarlaxe | 1,354 | 23rd June 2007 - 11:13 AM Last post by: Jarlaxe |
|||
![]() |
7 | truvu17 | 7,931 | 1st May 2006 - 03:20 PM Last post by: shadowx |
|||
![]() |
0 | Zenchi | 3,410 | 28th September 2004 - 03:35 AM Last post by: Zenchi |
|||
![]() |
3 | X3r0X | 5,201 | 28th September 2004 - 02:30 PM Last post by: X3r0X |
|||
![]() |
29 | alapidus | 6,291 | 6th February 2005 - 04:36 PM Last post by: mahesh2k |
|||
![]() |
5 | Goosestaf | 3,277 | 25th November 2004 - 07:05 AM Last post by: filipc |
|||
![]() |
1 | remonit | 6,606 | 4th May 2006 - 01:09 AM Last post by: beeseven |
|||
![]() |
1 | kvarnerexpress | 4,289 | 14th December 2004 - 12:18 AM Last post by: sandymc |
|||
![]() |
0 | podbicanin | 4,642 | 11th January 2005 - 10:55 PM Last post by: podbicanin |
|||
![]() |
2 | serverph | 5,739 | 6th December 2008 - 09:10 PM Last post by: Echo_of_thunder |
|||
![]() |
8 | zachtk8702 | 3,378 | 5th June 2009 - 05:13 AM Last post by: Gravity17 |
|||
![]() |
2 | zachtk8702 | 3,907 | 28th October 2006 - 04:42 PM Last post by: ghostrider |
|||
![]() |
9 | zachtk8702 | 9,989 | 21st May 2009 - 06:12 PM Last post by: jason8100 |
|||
![]() |
0 | zachtk8702 | 2,841 | 10th February 2005 - 03:26 AM Last post by: zachtk8702 |
|||
|
Open Discussion | Time is now: 4th July 2009 - 12:18 PM |
Web Hosting Powered by ComputingHost.com.