FTP dam FTP

a_jam_sandwich

Well-known member
Joined
Dec 10, 2002
Messages
367
Location
Uk
Currently im trying to write an FTP class but have run into problems. The below code connects to the server and gets the welcome message after that nothing yarda :confused: so I have no idea

see code below.

Code:
Imports System.Net
Imports System.Net.Sockets
Imports System.Text.Encoding

Module ModFTPClass

    Public Class classMyFTP

        Private _username As String = "anonymous"
        Private _password As String = ""
        Private _ip As String = ""
        Private _ISCONNECTED As Boolean = False

        Private FTP_Socket As New TcpClient
        Private FTP_networkStream As NetworkStream


        Public Event onError(ByVal ErrorMessage As String)

        Public Function Connect() As Boolean
            If OpenConnection() Then
                ReceiveCommand()
                SendCommand("USER " & _username)
                ReceiveCommand()
                SendCommand("PASS " & _password)
                ReceiveCommand()
                SendCommand("LS www")
                ReceiveCommand()
            End If
        End Function

        Private Function OpenConnection() As Boolean
            Try
                FTP_Socket.Connect("ftp.microsoft.com", 21)
                FTP_networkStream = FTP_Socket.GetStream()
                _ISCONNECTED = True
                Return True
            Catch ex As Exception
                RaiseEvent onError(ex.Message.ToString)
                Return False
            End Try
        End Function

        Private Function SendCommand(ByVal UserCommand As String)
            If _ISCONNECTED Then
                Dim MyCommand As Byte() = ASCII.GetBytes(UserCommand & vbCrLf)
                FTP_networkStream.Write(MyCommand, 0, MyCommand.Length)
            End If
        End Function

        Private Function ReceiveCommand() As String
            If _ISCONNECTED Then
                If FTP_networkStream.CanRead Then
                    Dim MyCommand(1024) As Byte
                    Dim BytesRead As Integer = 1
                    Dim ReceivedCommand As String
                    Dim Starttime As Long = Environment.TickCount
                    Do
                        BytesRead = FTP_networkStream.Read(MyCommand, 0, 1024)
                        Console.WriteLine(BytesRead)
                        ReceivedCommand += ASCII.GetChars(MyCommand)
                    Loop While FTP_networkStream.DataAvailable
                    Console.WriteLine(ReceivedCommand)
                End If
            End If
        End Function

    End Class

End Module

If anyone can figuar this out that would be great

Cheers

Andy
 
Just stepping through your code and the FTP server returns a "command not understood" error after you issue "SendCommand("LS www")" - is that the problem you mean?
 
Strange ??? not what i get. I changed it to use a socket instead and now it seams to work will post source soon
 
Now i have this

Code:
Imports System.Net
Imports System.Net.Sockets
Imports System.IO
Imports System.Text
Imports System.Text.Encoding

Module ModFTP

    Public Class classFTP

        Public LogWindow As TextBox

        Private MyFTPSocket As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)

        Public Function Connect()
            ConnectToHost()
            Response()
            Send("USER Anonymous")
            Response()
            Send("PASS [email]andrew_duff@btinternet.com[/email]")
            Response()
            Response()
            ListDirectory("")
        End Function

        Public Function RunCommand(ByVal Command As String)
            Send(Command)
            Response()
        End Function

        Private Function ConnectToHost()
            Dim MyHost As IPHostEntry = Dns.GetHostByName("ftp.microsoft.com")
            Dim MyEntry As New IPEndPoint(MyHost.AddressList(0), 21)
            MyFTPSocket.Connect(MyEntry)
            If Not LogWindow Is Nothing Then LogWindow.Text += "Connected to [" & MyHost.AddressList(0).ToString & "]" & vbCrLf
        End Function

        Public Function Send(ByVal Command As String)
            Try
                Dim SendBuffer As Byte() = ASCII.GetBytes(Command & Chr(13) & Chr(10))
                MyFTPSocket.Send(SendBuffer, SendBuffer.Length, 0)
                Console.WriteLine("Command Sent")
            Catch ex As Exception
            End Try
        End Function

        Public Function Response()
            Try
                Dim ReceiveBuffer(8000) As Byte
                Dim BytesReceived As Integer = MyFTPSocket.Receive(ReceiveBuffer)
                Console.WriteLine(BytesReceived)
                If Not LogWindow Is Nothing Then LogWindow.Text += ASCII.GetString(ReceiveBuffer, 0, BytesReceived)
            Catch ex As Exception
            End Try
        End Function

        Public Function ListDirectory(ByVal Directory As String)
            Try
                Dim BytesReceived As Integer
                Dim ReponseServerString As String
                Dim ReceiveBuffer(512) As Byte

                RunCommand("LIST")

                Do
                    BytesReceived = MyFTPSocket.Receive(ReceiveBuffer, 512, SocketFlags.Peek)
                    ReponseServerString += Encoding.ASCII.GetString(ReceiveBuffer, 0, BytesReceived)
                Loop Until BytesReceived = 0

                If Not LogWindow Is Nothing Then LogWindow.Text += ReponseServerString

            Catch ex As Exception
            End Try
        End Function

    End Class

End Module

Problem is the directory listing falls over and dies

any ideas

thanks

andy
 
Problem seems to be the bit
Code:
Do
    BytesReceived = MyFTPSocket.Receive(ReceiveBuffer, 512, SocketFlags.Peek)
    ReponseServerString += Encoding.ASCII.GetString(ReceiveBuffer, 0, BytesReceived)
Loop Until BytesReceived = 0

Im geting a result of "425 Cant open data connection" - however it can take ages to return this response.
It will go into a dead loop here as you are only peeking at the response and not removing it from the buffer.
Will see if I can find anything that could work here.
 
cheers I used the peek flag to see if anything was in the socket buffer there isnt I tried doing the same commands in telnet when connecting to the server and the same happens on telnet it doesnt return anything.

Im thinking maybe I just need to understand the FTP protocol

Andy
 
Ive setup an async receive now following code ...

Code:
        Public Function Response() As String
            Try
                Dim State As New classBuffer(512, MyFTPSocket)
                Dim ReceiveResult As IAsyncResult = MyFTPSocket.BeginReceive(State.Buffer, 0, State.BufferSize, 0, AddressOf ResponseCallback, State)
                ReceiveResult.AsyncWaitHandle.WaitOne(1, True)
                Return State.Response
            Catch ex As Exception
                Console.WriteLine(ex.ToString)
            End Try
        End Function

        Public Sub ResponseCallback(ByVal ar As IAsyncResult)
            Try
                Dim state As classBuffer = CType(ar.AsyncState, classBuffer)
                Dim Socket As Socket = state.Socket
                Dim BytesRead As Integer = Socket.EndReceive(ar)
                If BytesRead > 0 Then
                    Console.WriteLine("-->" & Encoding.ASCII.GetString(state.Buffer, 0, BytesRead))
                    state.Response += Encoding.ASCII.GetString(state.Buffer, 0, BytesRead)
                    Socket.BeginReceive(state.Buffer, 0, state.BufferSize, 0, AddressOf ResponseCallback, state)
                Else
                    receiveDone.Set()
                End If
            Catch ex As Exception
                Console.WriteLine(ex.ToString)
            End Try
        End Sub

The problem is

Code:
                ReceiveResult.AsyncWaitHandle.WaitOne(1, True)

If I do not put a timeout on the thread it hangs forever probley because of this line

Code:
                Dim BytesRead As Integer = Socket.EndReceive(ar)

Checking the help it says the above cause a stop indefinatly until data is received. It seams to me to be bad practice to rely on a timeout to stop the program from hanging?

Has anyone got any ideas?

Many thanks

Andy

P.s. Cheer so far PlausiblyDamp your comments are very usful
 
Blooming hell this is a nightmare which is now comming together didnt think async was so bad lol will post control and source when done.

BTW this is my first attemp at tcp using sockets so coding might be a bit weird

Andy
 
Right this is what I have come up with so far it connects in pasv mode

* Can display directory listing.

* Can change directory

* Can download files

There are problem with phasing the directory listings on Unix but windows server seems ok there is timeouts for every response

Have a look, it is still well in the alpha stage so dont exspect miricals but there is a demo proj file.

Any one want to add to it to build it up be my guest

Andy
 

Attachments

Back
Top