V tomto článku sa pozrieme na komunikáciu pomocou protokolu ftp. Ukážeme si, ako sa dá nadviazať spojenie s ftp servom, a ako nahrávať a sťahovať súbory.
Na začiatok je nevyhnutné pridať potrebné súbory. Je to hlavičkový súbor Wininet.h a knižnica Wininet.lib.
Na to, aby sme sa mohli pripojiť k ftp servu potrebujeme najprv získať manipulátor internetového pripojenia. Na to slúži funkcia
HINTERNET InternetOpen(
__in LPCTSTR lpszAgent,
__in DWORD dwAccessType,
__in LPCTSTR lpszProxyName,
__in LPCTSTR lpszProxyBypass,
__in DWORD dwFlags
);
Návratovou hodnotou tejto funkcie je práve manipulátor internetového pripojenia. V prípade chyby vráti funkcia NULL. Viac podrobnosti o tejto chybe sa môžete dozvedieť zavolaním funkcie GetLastError (viac o nej na msdn.com). Prvý parameter funkcie InternetOpen predstavuje názov nášho programu (v podstate tu môžete zadať hocičo). V http protokole je braný ako použitý prehliadač. Druhy parameter určuje typ pripojenia. Okrem iného sa dá nastaviť, či použiť proxy server a pod. možne hodnoty sú:
INTERNET_OPEN_TYPE_DIRECT,
INTERNET_OPEN_TYPE_PRECONFIG,
INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY,
INTERNET_OPEN_TYPE_PROXY
Ďalšie dva parametre sú potrebne pri použití proxy servera. Posledný parameter môže byť kombináciou nasledujúcich hodnôt:
INTERNET_FLAG_ASYNC,
INTERNET_FLAG_FROM_CACHE,
INTERNET_FLAG_OFFLINE.
Po tom ako máme prístup k internetu sa pripojíme sa k ftp serveru a to funkciou:
HINTERNET InternetConnect(
__in HINTERNET hInternet,
__in LPCTSTR lpszServerName,
__in INTERNET_PORT nServerPort,
__in LPCTSTR lpszUsername,
__in LPCTSTR lpszPassword,
__in DWORD dwService,
__in DWORD dwFlags,
__in DWORD_PTR dwContext
);
Prvý parameter je práve manipulátor internetového pripojenia, ktorý sme získali v predchádzajúcej funkcii. Nasledujúcim je meno (adresa) servera na ktorý sa chceme pripojiť. Môžeme tu zadať aj IP adresu v klasickom „bodkovom“ tvare. Ďalej je to port na ktorý sa pripájame pre ftp je to zvyčajne 21, čo predstavuje konštanta INTERNET_DEFAULT_FTP_PORT , ďalšie koštanty tvorí:
INTERNET_DEFAULT_FTP_PORT (21),
INTERNET_DEFAULT_GOPHER_PORT (70),
INTERNET_DEFAULT_HTTP_PORT (80),
INTERNET_DEFAULT_HTTPS_PORT (443),
INTERNET_DEFAULT_SOCKS_PORT (1080),
INTERNET_INVALID_PORT_NUMBER.
Potom nasleduje používateľské meno a heslo pri prihlasovaní na server.
Ďalej určime o aký typ služby ide (ftp/http apod.) a či chceme použiť pasívny mod ftp. Ak áno, použijeme INTERNET_FLAG_PASSIVE ako ďalší parameter. Posledný parameter môžeme opäť nechať NULL.
Návratovou hodnotou je manipulátor, ktorý nám umožní pracovať s týmto pripojením (nazvime si ho manipulátor FTP).
Po tom ako sme sa pripojili k serveru môžeme začať pracovať so súbormi a priečinkami. Na to slúžia funkcie:
Na vytvorenie priečinka:
BOOL FtpCreateDirectory(
__in HINTERNET hConnect,
__in LPCTSTR lpszDirectory
);
Prvý parameter je manipulátor FTP. A druhým názov priečinka. Aj funkcia prebehne v poriadku vráti true, inak false.
Pre odobratie priečinka je to:
BOOL FtpRemoveDirectory(
__in HINTERNET hConnect,
__in LPCTSTR lpszDirectory
);
Parametre a návratová hodnota podobne ako v predchádzajúcej funkcii.
Pre nahratie súboru použijeme funkciu:
BOOL FtpPutFile(
__in HINTERNET hConnect,
__in LPCTSTR lpszLocalFile,
__in LPCTSTR lpszNewRemoteFile,
__in DWORD dwFlags,
__in DWORD_PTR dwContext
);
Prvý parameter opäť manipulátor FTP, ďalej adresa súboru v lokálnom počítači (aj s cestou k súboru - môžete písať cestu od priečinka, z ktorého je spustený program.), ďalej nasleduje názov súboru na vzdialenom serveri. Ako ďalší parameter uvedieme kombináciu konštánt, ktoré určujú typ prenosu (ANCII a binarny) tie konštanty sú:
FTP_TRANSFER_TYPE_ASCII
FTP_TRANSFER_TYPE_BINARY
FTP_TRANSFER_TYPE_UNKNOWN
INTERNET_FLAG_TRANSFER_ASCII
INTERNET_FLAG_TRANSFER_BINARY
A poslednému parametru môžeme opäť priradiť hodnotu NULL.
Na získanie súboru zo servera môžeme použiť funkciu:
BOOL WINAPI FtpGetFile(
HINTERNET hConnect,
LPCTSTR lpszRemoteFile,
LPCTSTR lpszNewFile,
BOOL fFailIfExists,
DWORD dwFlagsAndAttributes,
DWORD dwFlags,
DWORD dwContext
);
Prvý parameter je nám už známy, ďalej je to názov súboru na serveri. Tretí parameter predstavuje názov (aj s cestou k súboru) na lokálnom počítači, kam sa uloží. Ak určime parameter fFailIfExists na true, potom v prípade, že súbor už na danej adrese v počitači existuje, funkcia zlyhá. Ďalej uvádzame kombináciu konštánt, ktoré sú rovnaké, ako vo funkcii CreateFile:
BOOL WINAPI FtpGetFile(
FILE_ATTRIBUTE_ARCHIVE
FILE_ATTRIBUTE_COMPRESSED
FILE_ATTRIBUTE_HIDDEN
FILE_ATTRIBUTE_NORMAL
FILE_ATTRIBUTE_READONLY
FILE_ATTRIBUTE_ROMMODULE
FILE_ATTRIBUTE_SYSTEM
Ďalšie 2 parametre sú rovnaké ako v predchádzajúcej funkcii.
Prikladám kód ukážkového programu, ktorý sa pri spustení pripojí na server, nahrá a stiahne z neho súbor. Tieto súbory musia už pred spustením programu existovať. Ich názvy môžete nastaviť v zdrojovom kóde. Ukážkový program je vytváraný v prostredí MS Visual 2008.
#include
#include
#include
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//premenne potrebne pre ftp
HINTERNET internet;
HINTERNET ftp;
char stiahni[30] = "stiahni.txt";
char nahraj[30] = "nahraj.txt";
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
TCHAR szAppName[] = TEXT("Nazdárek celičkej světe:-)");
HWND hWnd;
MSG msg;
WNDCLASSEX wc;
wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hIconSm = NULL;
wc.hCursor = (HCURSOR)LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = szAppName;
RegisterClassEx(&wc);
hWnd = CreateWindowEx(0,szAppName,
szAppName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,NULL);
ShowWindow(hWnd, iCmdShow);
UpdateWindow(hWnd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_CREATE:
internet = InternetOpen(_T("Naš ftp client"),INTERNET_OPEN_TYPE_DIRECT,NULL,NULL,INTERNET_FLAG_ASYNC); //ziskame pristup k internetu bez pouzitia proxy servra
if(internet==NULL)
{MessageBox(hWnd,_T("Nepodarilo sa pripojiť k internetu. \nProsím skontrolujte stav Vášho pripojenia!"),_T("Chyba"),MB_OK | MB_ICONWARNING);
break;}
ftp = InternetConnect(internet,/*adresa servra*/,INTERNET_DEFAULT_FTP_PORT,/*použivateľské meno*/,/*heslo*/,INTERNET_SERVICE_FTP,INTERNET_FLAG_PASSIVE ,NULL); //získame pristup k ftp servru
if(ftp==NULL)
{MessageBox(hWnd,_T("Nepodarilo sa pripojiť k ftp. \nProsím skontrolujte Vaše nastavenia!"),_T("Chyba"),MB_OK | MB_ICONWARNING);
break;}
if(!FtpPutFile(ftp,nahraj,nahraj,FTP_TRANSFER_TYPE_BINARY,NULL))
{MessageBox(hWnd,_T("Nepodarilo sa nahrať subor. \nProsím skontrolujte či subor existuje!"),_T("Chyba"),MB_OK | MB_ICONWARNING);
break;}
if(!FtpGetFile(ftp,stiahni,stiahni,false,FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_BINARY,NULL))
{MessageBox(hWnd,_T("Nepodarilo sa stiahnuť súbor. \nProsím skontrolujte či subor existuje!"),_T("Chyba"),MB_OK | MB_ICONWARNING);
break;}
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
Pre jednoduchosť sa všetky činnosti vykonajú hneď pri spustení programu. Myslím, že vďaka seriálu o Win 32API na tomto serveri by ste nemali mať problém vytvoriť nejake graficky prijemne rozhranie. Napríklad nahrávanie a sťahovanie by sa mohlo ovládať tlačitkami a názvy načítavať z textových poli.