Ftp Connect

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
MOV
Постоялец
Постоялец
 
Сообщения: 414
Зарегистрирован: 13.03.2004 (Сб) 15:13
Откуда: Санкт-Петербург

Ftp Connect

Сообщение MOV » 01.04.2006 (Сб) 15:28

Даже здесь по поиску не нашел простого и доступного способа
законнектиться к фтп :oops:
надо уметь:
-читать список файлов директории на фтп
-скачать файл с фтп
-закачать файл на фтп

Roman-vb
Обычный пользователь
Обычный пользователь
 
Сообщения: 91
Зарегистрирован: 24.01.2006 (Вт) 18:31
Откуда: БРЯНСК

Сообщение Roman-vb » 01.04.2006 (Сб) 16:38

Работа с FTP протоколом на Visual Basic
Источник: http://dlczone.narod.ru/
Перевод статьи Joacim Andersson "Using FTP in VB" (Работа с FTP протоколом на Visual Basic)
В моей последней разработке нужно было использовать функции работы с FTP. Сначала для этой цели я использовал Internet Transfer Controls, но вскоре понял, что этот компонент заточен более на работу с Http. У ITC были проблемы с серверами, на которых было установлено не Микрософтовское ПО (ну, например Apache). Тогда я решил написать собственный FTP компонент в виде класса (совокупности объектов или функций в группе по их свойству и поведению). После часов поиска в MSDN я обнаружил очень интересные функции FtpPutFile, FtpGetFile, FtpCreateDirectory. Работа этих функций становилась возможной при получении данных (хендла) от функции InternetConnect, которая используется для обращения к определенным портам адреса (IP). Но и ей нужна информация от функции InternetOpen. Таким образом, для использования каких-либо FTP команд необходимо последовательно вызвать эти функции. При завершении работы нужно вызвать функцию InternetCloseHandle два раза, чтобы закрыть FTP и Internet сессии.
Правильная последовательность функций:
· Инициализируем работу с интернет функциями через InternetOpen
· Коннектимся к хосту через InternetConnect
· Используем FTP команды
· Закрываем хендлы
Пожалуй, настало время подтвердить теоретическую часть статьи примерами. Для начала самое основное - функция FTPGetFile для получения файла от сервера. Вот так эта функция объявляется:
Private Declare Function FtpGetFile _
Lib "wininet.dll" Alias "FtpGetFileA" ( _
ByVal hFtpSession As Long, _
ByVal lpszRemoteFile As String, _
ByVal lpszNewFile As String, _
ByVal fFailIfExists As Boolean, _
ByVal dwFlagsAndAttributes As Long, _
ByVal dwFlags As Long, _
ByVal dwContext As Long) As Boolean
Как я уже писал, нам понадобятся функции InternetOpen и InternetConnect. Они объявляются так:
Private Declare Function InternetOpen _
Lib "wininet.dll" Alias "InternetOpenA" ( _
ByVal sAgent As String, _
ByVal nAccessType As Long, _
ByVal sProxyName As String, _
ByVal sProxyBypass As String, _
ByVal nFlags As Long) As Long

Private Declare Function InternetConnect _
Lib "wininet.dll" Alias "InternetConnectA" ( _
ByVal hInternetSession As Long, _
ByVal sServerName As String, _
ByVal nServerPort As Integer, _
ByVal sUserName As String, _
ByVal sPassword As String, _
ByVal nService As Long, _
ByVal dwFlags As Long, _
ByVal dwContext As Long) As Long
Рассмотрим каждый из четырех шагов в отдельности.
Сначала Шаг первый: Подключение к Интернет.
hINetSession = InternetOpen("MyFTPClient", 0, vbNullString, vbNullString, 0)
Первый параметр (sAgent) указывает на имя программы, которая вызывает функцию. Видимо, здесь можно писать все, что угодно. Второй параметр (nAccessType) может принимать всего три значения - 0,1 и 3. Он определяет, используем ли мы прокси или нет. При значении равном 1 мы коннектимся напрямую. При 3-х мы используем прокси. При этом адрес прокси нужно задать в параметре sProxyName и порт в параметре sProxyBypass. В данном примере для соединения я установил значение 0, при котором функция берет всю информацию из реестра (то есть использует настройки IE). Т.к. мы не определяем прокси-сервер напрямую, то третий и четвертый параметры принимают значение vbNullString. Последний параметр dwFlags определяет работу функции. Ничего нестандартного в этом случае нам не требуется, поэтому просто ставим 0.
Если вызов функции прошел удачно, то переменной hINetSession присвоится ненулевое значение, представляющее собой хендл функции, который мы используем чуть позже.
Шаг второй: производим коннект.
hSession = InternetConnect(hINetSession, "ftp.microsoft.com",
"21", "anonymous", "guest", INTERNET_SERVICE_FTP, 0, 0)
Первый параметр InternetConnect представляет собой хендл, полученный при выполнении InternetOpen. Второй - урл или Ip хоста, к которому мы присоединяемся (при этом ftp:// опускается). Следующим параметром идет порт. Я выставил значение порта равное 21, но если вы поставите 0, то ничего страшного не произойдет. Просто программа будет коннектиться через порт по умолчанию (как раз 21). Далее мы передаем логин и пароль. Будьте осторожны! При дизассмеблировании все ваши пароли могут попасть в руки особо старательных крякеров. Следующим параметром мы определяем тип используемого сервиса. Я использовал зарезервированную константу INTERNET_SERVICE_FTP, которая имеет значение 1. Также могут быть использованы следующие значения:

Private Const INTERNET_SERVICE_FTP = 1
Private Const INTERNET_SERVICE_GOPHER = 2
Private Const INTERNET_SERVICE_HTTP = 3
Сейчас нас интересует только FTP. Если выставить 0, то функция сама определит, что нам требуется. В этом случае в параметре sServerName следует указать полный урл (ftp://ftp.pesh.com)
Параметр dwFlags мы могли установить на &H8000000 (или INTERNET_FLAG_PASSIVE), если бы нам потребовалось работать в FTP в пассивном режиме. Здесь мы просто пишем 0. Последний параметр dwContext определяет необходимость возврата функцией значений. Нам это не нужно, поэтому 0.
Шаг третий: вызов FTP функций (например, FTPGetFile)
Сначала мы объявим эту функцию:
Private Declare Function FtpGetFile _
Lib "wininet.dll" Alias "FtpGetFileA" ( _
ByVal hFtpSession As Long, _
ByVal lpszRemoteFile As String, _
ByVal lpszNewFile As String, _
ByVal fFailIfExists As Boolean, _
ByVal dwFlagsAndAttributes As Long, _
ByVal dwFlags As Long, _
ByVal dwContext As Long) As Boolean
Потом нам остается только вызвать ее:
If FtpGetFile(hSession, "dirmap.htm", "c:\dirmap.htm", False, 0, 1, 0) = False Then
MsgBox "Call to FtpGetFile Failed!"
End If
Первым идет хендл от функции InternetConnect. Далее имя (или полный путь) до файла на удаленном сервере. Третий параметр - путь до места назначения. Параметр №4 fFailExists определяет, как будет вести себя программа, если она обнаружит, что файл с таким именем уже существует. Значение false указывает на то, что такие файлы будут перезаписываться. Атрибуты, присваиваемые локальному файлу, задаются в параметре dwFlagAttributes. Это можно сделать и после. За формат передачи данных отвечает параметр dwFlags: ASCII = 1, Binary = 2. Последний параметр также отвечает за возврат значений.
Пункт четвертый, заключительный: закрываем хендлы
Хендлы закрываются в порядке, противоположном их открытию. Сначала закроем hSession, а потом InetSession. Для этого используем функцию InternetCloseHandle.
Private Declare Function InternetCloseHandle _
Lib "wininet.dll" (ByVal hInet As Long) As Integer
Так она вызывается:
Call InternetCloseHandle(hSession)
Call InternetCloseHandle(hINetSession)
Готово! Мы скачали файл. Теперь разберемся с другими функциями.
Для отправки файла на сервер выполняем шаги 1 и 2 и вызываем функцию FTPPutFile, которая выглядит так:
Private Declare Function FtpPutFile _
Lib "wininet.dll" Alias "FtpPutFileA" ( _
ByVal hFtpSession As Long, _
ByVal lpszLocalFile As String, _
ByVal lpszRemoteFile As String, _
ByVal dwFlags As Long,
ByVal dwContext As Long) As Boolean
Как видите, очень похоже на FTPGetFile.
Сначала идет хендл от InternetConnect, путь и имя локального и "удаленного" файлов. Параметр dwFlags задает тип передачи ASCII = 1, Binary = 2; последний аргумент опускаем.
If FtpPutFile(hSession, "c:\MyFile.txt", "shared.txt", 1, 0) = False Then
MsgBox "The call to FtpPutFile failed."
End If
Вызов функции может оказаться неуспешным, если у пользователя нет прав закачивать файлы на сервер.
УДАЛЯЕМ ФАЙЛ
Private Declare Function FtpDeleteFile _
Lib "wininet.dll" Alias "FtpDeleteFileA" ( _
ByVal hFtpSession As Long, _
ByVal lpszFileName As String) As Boolean
Здесь просто выставляем хендл и имя удаляемого файла. Опять может не сработать при отсутствии прав на удаление.
ПЕРЕИМЕНОВАНИЕ
Private Declare Function FtpRenameFile _
Lib "wininet.dll" Alias "FtpRenameFileA" ( _
ByVal hFtpSession As Long, _
ByVal lpszExisting As String, _
ByVal lpszNewName As String) As Boolean
Снова требуется только хендл и имена файлов(старое и новое)
ПОЛУЧАЕМ СПИСОК ФАЙЛОВ и ДИРЕКТОРИЙ НА СЕРВЕРЕ
Как вы могли заметить, все вышеописанные функции очень просты. Вот пример посложнее. Значения функции могут выводится в Листбокс или его аналог. Нам потребуются две функции FtpFindFirstFile и InternetFindNextFile:

Private Declare Function FtpFindFirstFile _
Lib "wininet.dll" Alias "FtpFindFirstFileA" ( _
ByVal hFtpSession As Long, _
ByVal lpszSearchFile As String, _
ByRef lpFindFileData As WIN32_FIND_DATA,
ByVal dwFlags As Long, _
ByVal dwContent As Long) As Long

Private Declare Function InternetFindNextFile _
Lib "wininet.dll" Alias "InternetFindNextFileA" ( _
ByVal hFind As Long, _
ByRef lpvFindData As WIN32_FIND_DATA) As Long
Эти функции возвращают ненулевое значение при обнаружении файла и 0, если произошла ошибка. Для того чтобы определить реальная ли это ошибка или просто больше нет файлов нужно, проверить значение Err.LastDllError. Если оно равно ERROR_NO_MORE_FILES (=18), то все нормально, если нет, то дело наше плохо.
Обе этих функции имеют параметр WIN32_FIND_DATA, который представляет собой тип или структуру, определяемую юзером.
Private Type WIN32_FIND_DATA
dwFileAttributes As Long
ftCreationTime As FILETIME
ftLastAccessTime As FILETIME
ftLastWriteTime As FILETIME
nFileSizeHigh As Long
nFileSizeLow As Long
dwReserved0 As Long
dwReserved1 As Long
cFileName As String * 260
cAlternate As String * 14
End Type
Подструктура FILENAME:
Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
Далее я привожу пример заполнения ListBox файлами и директориями с сервера. Считаем, что вы уже получили FTP хендл c именем hSession.
Private Sub ListFiles()
Dim hFile As Long ' This is a file handle
Dim fd As WIN32_FIND_DATA
hFile = FtpFindFirstFile(hSession, "*.*", fd, 0, 0)
If hFile = 0 Then
If Err.LastDLLError = ERROR_NO_MORE_FILES Then
MsgBox "No files found"
Exit Sub
Else
MsgBox "Some error occurred"
Exit Sub
End If
End If
Do
List1.AddItem fd.cFileName
Loop While InternetNextFile(hFile, fd) <> 0
'Close the file handle
Call InternetCloseHandle(hFile)
End Sub
Заключение.
Как вы видите, описывать FTP функции очень просто. Конечно, есть ещё много разных функций, типа создания директории, но их также легко написать, главное не забывайте закрывать хендлы.

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 01.04.2006 (Сб) 16:40

Гм... Для наглядности можно было б хоть код в теги заключить...
А я все практикую лечение травами...

Roman-vb
Обычный пользователь
Обычный пользователь
 
Сообщения: 91
Зарегистрирован: 24.01.2006 (Вт) 18:31
Откуда: БРЯНСК

Сообщение Roman-vb » 01.04.2006 (Сб) 16:44

Twister
Ну поспешил человек...поочь захотел :P

MOV
Постоялец
Постоялец
 
Сообщения: 414
Зарегистрирован: 13.03.2004 (Сб) 15:13
Откуда: Санкт-Петербург

Сообщение MOV » 01.04.2006 (Сб) 16:44

Гуд. Бальшое спаибо. Иду испытвать.

MOV
Постоялец
Постоялец
 
Сообщения: 414
Зарегистрирован: 13.03.2004 (Сб) 15:13
Откуда: Санкт-Петербург

Сообщение MOV » 01.04.2006 (Сб) 17:27

Так и не догнал

если есть строка подключения типа

ftp://sumdurak:HR18r12K@143.0.52.31


как ее воткнуть праильно в InternetConnect у меня она возвращает 0
как только ни пробовал

Я так думаю, надо так:

hSession = InternetConnect(hINetSession, "143.0.52.31", _
"21", "sumdurak", "HR18r12K", 0, 0, 0)


И IE у меня коннектится по этой строке (ну не совсем по этой конечно)
само подключение
InternetOpen
тоже проходит, а вот
InternetConnect
нифига

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 01.04.2006 (Сб) 18:26

Не относящийся к теме топика мат в исполнении Roman-vb вырезан и вместе с контекстом сохранён для истории в надёжном месте.
Вопрос о бане Roman-vb будет поставлен перед администрацией в течение ближайших двух минут.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Kovu
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 924
Зарегистрирован: 29.04.2005 (Пт) 17:38

Сообщение Kovu » 01.04.2006 (Сб) 21:13

MOV
Попробуй сделать
Параметр dwFlags мы могли установить на &H8000000 (или INTERNET_FLAG_PASSIVE), если бы нам потребовалось работать в FTP в пассивном режиме

т.к. большинство фтп именно в таком режиме и работают
Если всё делать своими ручками, они скоро отвалятся !

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 01.04.2006 (Сб) 21:29

Большинство серверов работают в обоих режимах.
Серверов, которые работали бы только в пассивном, я не встречал.
Только в активном -- встречал.
Изображение

Kovu
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 924
Зарегистрирован: 29.04.2005 (Пт) 17:38

Сообщение Kovu » 01.04.2006 (Сб) 21:33

tyomitch
не буду спорить, в моей локальной сети все серверы именно в пассивном режиме работают :)
Если всё делать своими ручками, они скоро отвалятся !

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 01.04.2006 (Сб) 21:50

Kovu писал(а):tyomitch
не буду спорить, в моей локальной сети все серверы именно в пассивном режиме работают :)

Хочешь сказать, активный режим на них запрещён? :shock:
Изображение

MOV
Постоялец
Постоялец
 
Сообщения: 414
Зарегистрирован: 13.03.2004 (Сб) 15:13
Откуда: Санкт-Петербург

Сообщение MOV » 02.04.2006 (Вс) 8:49

Kovu, не пробовал и 0 ставить в dwFlags и &H8000000 - все равно не коннектится и функция возвращает 0

Kovu
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 924
Зарегистрирован: 29.04.2005 (Пт) 17:38

Сообщение Kovu » 02.04.2006 (Вс) 12:14

tyomitch
Именно так, а что вызывает такое удивление? :)
Если всё делать своими ручками, они скоро отвалятся !

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 02.04.2006 (Вс) 12:31

Удивление вызывает цель такой странной политики.
Изображение

MOV
Постоялец
Постоялец
 
Сообщения: 414
Зарегистрирован: 13.03.2004 (Сб) 15:13
Откуда: Санкт-Петербург

Сообщение MOV » 03.04.2006 (Пн) 9:33

никто не в курсе что еще может быть
втыкаю url в IE - коннектится
а через API+VB не хочет

MOV
Постоялец
Постоялец
 
Сообщения: 414
Зарегистрирован: 13.03.2004 (Сб) 15:13
Откуда: Санкт-Петербург

Сообщение MOV » 03.04.2006 (Пн) 13:05

Ура!!! Всем огромное спасибо 2-й степени! :D
Заработало!
надо было:
Код: Выделить всё
hSession = InternetConnect(hINetSession, "143.0.52.31", _
"21", "sumdurak", "HR18r12K", [b]1[/b], 0, 0)


единичку, где nService


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 177

    TopList