11. Komponenty NetMasters I

Komponenty firmy NetMasters jsou umístěny na stránce Internet palety komponent. Tyto komponenty je možno rozdělit do následujících skupin:

Další komponenty NetMasters budou popsány v následujících kapitolách.

Jednotka PSock

Jednotka PSock obsahuje komponentu TPowersock, základní třídu pro FastNet Tools C++ Builderu a komponentu TNMGeneralServer, obecný Internetovský server, který může být použit k odvozování svých vlastních zákaznických serverů. Také obsahuje několik funkcí, které mohou být užitečné pro vývoj Internetovských aplikací.
V jednotce jsou tyto komponenty: a tyto funkce:

Komponenta TPowersock

Komponenta TPowersock je základní třída pro většinu ostatních komponent v FastNet Tools. Může být použita jako základ pro vytváření ovladačů které pracují s jinými protokoly nebo pro vytváření zákaznických protokolů.
Komponenta TPowersock slouží jako základní třída pro TCP komunikace používající různé protokoly Internetu. Může být použita k vytvoření nového protokolu, který obsluhuje protokoly nepodporované FastNet Tools nebo k vytvoření nového protokolu k řešení zákaznického problému.
Nepředpokládá se, že komponenta TPowersock bude používána jako samostatná komponenta. Od komponenty TPowersock ale odvozujeme další třídy. Když již od TPowersock máme odvozenou svoji komponentu, pak pokud máme nastaveny vlastnosti Host a Port, klient se může připojit voláním metody Connect ke vzdálenému hostiteli. Data mohou být přijímána od vzdáleného hostitele voláním metod read, ReadLn, CaptureFile, CaptureStream a CaprtureString. Data můžeme zasílat na vzdáleného hostitele voláním metod write, writeln, SendFile a SendStream. Metoda Transaction zasílá data na vzdáleného hostitele a čte odpověď ze serveru.
Pokud se chystáme vytvořit novou komponentu odvozením od komponenty TPowersock, pak v jejím zdrojovém kódu nalezneme více detailů o vnitřní práci TPowersock. Jestliže nemáme zdrojový kód pro FastNet Tools pro C++ Builder, pak jej můžeme získat na http://www.netmastersllc.com.
Komponenta má následující vlastnosti (komponenty NetMasters jsou zapsány v Object Pascalu; deklarace uvedené v této a dalších kapitolách k popisování vlastností, metod a událostí komponent NetMasters, jsou také zapsány v Object Pascalu):
 
Deklarace Popis Rozsah Dostupnost
property BeenCanceled: boolean; Vlastnost má hodnotu true, pokud současná operace má být zrušena, a false jestliže současná operace nemá týt zrušena. Public Runtime, Readonly
property BeenTimedOut: boolean; Vlastnost má hodnotu true, pokud pro současnou operaci vypršel čas nebo false, jestliže čas nevypršel. Public Runtime, Readonly
property BytesRecvd: longint; Vlastnost obsahuje počet slabik přijatých v současném přenosu dat. Public Runtime, Readonly
property BytesSent: longint; Vlastnost obsahuje počet slabik odeslaných v průběhu současné datové transakce. Public Runtime, Readonly
property BytesTotal: longint; Vlastnost obsahuje celkový počet slabik přijatých nebo odeslaných v současné datové transakci. Public Runtime, Readonly
property Connected: boolean; Vlastnost má hodnotu true pokud klient je připojen na vzdáleného hostitele a false pokud připojen není. Public Runtime, Readonly
property Handle: tSocket; Madlo soketu právě používaného pro komunikaci WinSock. Používáme při přímém volání API WinSock. Public Runtime, Readonly
property Host: String; Vlastnost obsahuje jméno nebo tečkovou IP adresu vzdáleného hostitele pro připojení. Published Runtime, Designtime
property LastErrorNo: integer; Vlastnost obsahuje poslední oznámenou chybu soketu. Public Runtime
property LocalIP: string; Vlastnost obsahuje tečkovou IP adresu lokálního počítače. Je-li více než jedna IP adresa, pak je vracena pouze první. Public Runtime, Readonly
property Port: Integer; Vlastnost specifikuje číslo portu na vzdáleném hostiteli, ke kterému se připojujeme nebo v případě serveru, číslo portu na kterém server naslouchá. Published Runtime*, Designtime
property RemoteIP: string; Vlastnost obsahuje tečkovou IP adresu vzdáleného hostitele. Vlastnost není nastavena dokud klient není připojen na vzdáleného hostitele. Public Runtime, Readonly
property ReplyNumber: Smallint; Vlastnost obsahuje číselný výsledek transakce (je-li). Public Runtime, Readonly
property ReportLevel: integer; Vlastnost řídí množství detailů, které jsou oznamovány událostí OnStatus a vlastností Status. Možné hodnoty jsou: Status_None = 0, Status_Informational = 1, Status_Basic = 2,  Status_Routines = 4, Status_Debug = 8 a Status_Trace = 16. Implicitní hodnota je Status_Informational Published DesignTime, RunTime
property Status: String; Vlastnost obsahuje poslední stavovou zprávu, která byla předána jako parametr stavu v události OnStatus. Public RunTime, ReadOnly
property TimeOut: Integer; Vlastnost specifikuje množství času (v milisekundách) čekání na odpověď od soketu před generováním výjimky a zrušením současné operace. Pokud TimeOut je 0, pak výjimka není nikdy generována a čas operace nikdy nevyprší. Implicitní hodnota: 0. Published Designtime, Runtime
property TransactionReply: String; Vlastnost obsahuje výsledek od posledního příkazu zaslaného na server. Public Runtime, ReadOnly
property WSAInfo: TStringList; Vlastnost obsahuje informace o současné verzi Winsock (číslo verze a výrobce). Public Runtime, ReadOnly

* V případě TNMGeneralServer, vlastnost Port musí být nastavena během návrhu.

Následuje stručný popis metod komponenty. Je zde uvedena deklarace (v Object Pascalu), popis, popis parametrů a vracená hodnota.

function Accept: Word; virtual;
Metoda akceptuje připojení ze vzdáleného počítače, který požaduje připojení. Soket akceptující připojení je návratová hodnota. Výsledkem funkce je popis soketu pro připojení klienta.

function read(value: word): string;
Metoda čte specifikovaný počet slabik ze současně připojeného soketu a vrací jej jako řetězec. Parametr specifikuje počet slabik, který má být přečten ze soketu. Jestliže value = 0, pak jsou čtena všechna data vracená soketem.

function ReadLn: string;
Metoda čte data ze soketu dokud není nalezeno odřádkování a vrací data jako řetězec.

function Transaction(const CommandString: String): String; virtual;
Metoda zasílá příkaz vzdálenému hostiteli a vrací odpověď od hostitele jako řetězec. Je také nastavena vlastnost ReplyNumber na číselnou hodnotu odpovědi (je-li). Parametr specifikuje příkaz zasílaný na server.

procedure Abort; virtual;
Metoda ruší současnou operaci. Tato metoda je ve svých potomcích přepisována, protože každá operace má jiné požadavky na operaci zrušení.

procedure Cancel;
Metoda ruší současnou vstupní nebo výstupní operaci a odpojuje se od vzdáleného hostitele. Když je volána metoda Cancel, pak je generována výjimka.

procedure CaptureFile(FileName: String);
Metoda zabere všechna data ze soketu a uloží je v souboru specifikovaném parametrem. Data budou odebírána ze soketu, dokud soket není uzavřen. Parametr musí být přípustná specifikace souboru (může být uvedena i adresářová cesta).

procedure CaptureStream(MainStream: TStream; Size: longint);
Metoda zabírá data ze soketu dokud není získán specifikovaný počet slabik. Parametr MainStream specifikuje proud použitý pro uložení dat a parametr Size určuje počet čtených slabik do proudu. Pokud Size je -1, pak data jsou čtena do proudu dokud soket není uzavřen.

procedure CaptureString(var AString: String; Size: longint);
Metoda přebírá data specifikované velikosti ze soketu a ukládá je do řetězce. Prvním parametrem je řetězcová proměnná do které jsou ukládána data, druhý parametr specifikuje počet čtených slabik ze soketu do řetězce. Pokud Size je -1, pak data jsou čtena do proudu dokud soket není uzavřen.

procedure CertifyConnect;
Metoda testuje zda vidí připojení klienta ke vzdálenému hostiteli. Pokud připojení neexistuje je generována událost OnConnectionRequired. Tato událost je v TPowersock chráněná, ale v jeho potomcích je zveřejněna.

procedure Connect; virtual;
Metoda připojuje klienta ke vzdálenému hostiteli. Před voláním metody musí být nastaveny vlastnosti Host a Port. V komponentách specifických protokolů, potomcích TPowersock vlastnost Port je již nastavena na standardní port protokolu. Pokud jméno hostitele je chybné, pak je generována výjimka, jestliže proměnná Handled v události OnInvalidHost není nastavena na true, nebo pokud událost OnInvalidHost nenastavuje chybné jméno hostitele na přípustné jméno hostitele. Pokud připojení je neúspěšné, pak vzniká událost OnConnectionFailed a je generována výjimka.

procedure Disconnect; virtual;
Metoda odpojuje klienta od vzdáleného hostitele. Při úspěšném odpojení vzniká událost OnDisconnect.

procedure FilterHeader(HeaderStream: TFileStream);
Metoda filtruje výstup hlavičky MIME z dat získaných připojeným soketem a ukládaných do HeaderStream. Parametr specifikuje souborový proud k uložení hlavičky MIME.

procedure Listen(sync: boolean);
Metoda naslouchá TCP připojení na portu specifikovaném vlastností Port. Pokud parametr je false, pak při navázání připojení vzniká událost OnAccept, ve které připojení může být akceptováno metodou Accept nebo může být ignorováno. Jestliže parametr je true, pak volání Accept musí být provedeno přímo po volání Listen k akceptaci připojení.

procedure RequestCloseSocket;
Metoda uzavírá současné aktivní soket, ale neuvolňuje jej.

procedure SendBuffer(value: PChar; buflen: word);
Metoda zasílá data z vyrovnávací paměti na vzdáleného hostitele. První parametr specifikuje vyrovnávací paměť s odesílanými daty a druhý parametr určuje počet slabik, které budou odeslány z vyrovnávací paměti.

procedure SendFile(FileName: String);
Metoda odesílá obsah souboru na vzdáleného hostitele. Parametr specifikuje jméno odesílaného souboru (může obsahovat i adresářovou cestu).

procedure SendStream(MainStream: TStream);
Metoda odesílá obsah proudu na vzdáleného hostitele. Parametr specifikuje proud obsahující odesílaná data.

procedure write(value: String);
Metoda odesílá řetězec na vzdáleného hostitele. Odesílaný řetězec je určen parametrem. Na konec přenášeného řetězce není připojeno odřádkování.

procedure writeln(value: string);
Metoda odesílá řetězec na vzdáleného hostitele. Odesílaný řetězec je určen parametrem. Na konec řetězce je připojeno odřádkování.

Komponenta TPowersock má tyto události:

property OnConnect: TNotifyEvent;
Událost vzniká, když je zřízeno připojení na vzdáleného hostitele. Odpovídá zprávě FD_CONNECT WinSock.

property OnHostResolved: TOnHostResolved;
Událost vzniká, když adresa vzdáleného hostitele je převedena na tečkovou IP adresu. Pokud specifikované jméno hostitele nebo IP adresa je chybná, pak není generována událost OnHostResolved, ale událost OnInvalidHost.

property OnStatus: TOnStatus;
Událost vzniká, když se změní stav komponenty.

property OnConnectionFailed: TNotifyEvent;
Událost vzniká, když nelze zřídit připojení na vzdáleného hostitele.

property OnDisconnect: TNotifyEvent;
Událost vzniká při odpojení klienta od serveru. Odpovídá zprávě FD_CLOSE WinSock.

property OnInvalidHost: THandlerEvent;
Událost vzniká, když hostitel specifikovaný vlastností Host je nepřípustný. Pokud parametr Handled je nastaven na true pak je zopakován pokus o připojení. Když Handled je false, pak je generována výjimka.

property OnPacketRecvd: TNotifyEvent;
Událost nastává, když data jsou přijmuta ze vzdáleného hostitele. Používáme společně s vlastnostmi BytesRecvd a BytesTotal k monitorování průběhu zpracování dat.

property OnPacketSent: TNotifyEvent;
Událost nastává, když data jsou odeslána na vzdáleného hostitele. Používáme společně s vlastnostmi BytesSent a BytesTotal k monitorování průběhu zpracování dat.

Komponenta TPowersock není určena pro přímé použití v našich aplikacích (i když může být použita). Následuje několik příkladů objasňujících význam a použití jednotlivých metod, vlastností a událostí této komponenty (někdy je k demonstraci použit některý potomek TPowersock).

Příklad 1
K vytvoření tohoto příkladu začneme novou aplikaci a na formulář vložíme komponenty TButton, TMemo a TPowersock. Do obsluhy události OnClick tlačítka vložíme následující kód:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  Powersock1->Host = "www.netmastersllc.com";
  Powersock1->Port = 13;
  Powersock1->Connect();
}
Do obsluhy události OnConnect ovladače TPowersock vložíme kód:
void __fastcall TForm1::Powersock1Connect(TObject *Sender)
{
  Memo1->Liens->Add("Connected");
  Memo1->Lines->Add("Local Address: "+Powersock1->LocalIP);
  Memo1->Lines->Add("Remote Address: "+Powersock1->RemoteIP);
}
Obsluha události OnHostResolved ovladače TPowersock vypadá takto:
void __fastcall TForm1::Powersock1HostResolved(TComponent *Sender)
{
  Memo1->Lines->Add("Host Resolved");
}
Vytvoříme ještě obsluhu OnStatus ovladače TPowersock s kódem:
void __fastcall TForm1::Powersock1Status(TComponent *Sender,
     AnsiString Status)
{
  Memo1->Lines->Add(Powersock1->Status);
  Memo1->Lines->Add("Last WinSock error: "+IntToStr(Powersock1->LastErrorNo));
  if (Powersock1->BeenCanceled)
    Memo1->Lines->Add("Input/ouput operation canceled");
  if (Powersock1->BeenTimedOut)
    Memo1->Lines->Add("Operation timed out");
}
Spustíme aplikaci a stiskneme tlačítko. Po stisku tlačítka je zřízeno připojení na www.netmastersllc.com na port 13. Po převedení www.netmastersllc.com na přípustnou IP adresu, pak obsluha OnHostResolved přidá do komponenty Memo řádek Host Resolved. Když je zřízeno připojení pak OnConnect aktualizuje Memo k informování uživatele, že připojení bylo zřízeno. Jsou také vypsány tečkové IP adresy lokálního počítače (vlastnost LocalIP) a vzdáleného počítače (vlastnost RemoteIP). Jak jsou dostupné stavové zprávy, pak do Memo jsou přidány další řádky, stejně jako poslední zjištěná chyba Winsock. Pokud současná operace má být zrušena, pak vlastnost BeenCanceled je true a pokud pro současnou operaci vypršel čas, pak vlastnost BeenTimedOut má hodnotu true.

Příklad 2
Pro vytvoření dalšího příkladu začneme novou aplikací. Na formulář vložíme komponenty TStatusBar, TButton a TNMHTTP a nastavíme vlastnost SimplePanel komponenty stavového řádku na true.
Vytvoříme obsluhu události OnPacketRecvd komponenty TNMHTTP s následujícím příkazem:
void __fastcall TForm1::NMHTTP1PacketRecvd(TObject *Sender)
{
  StatusBar1->SimpleText = IntToStr(NMHTTP1->BytesRecvd)+
       " bytes out of "+IntToStr(NMHTTP1->BytesTotal)+" transferred";
}
Obsluha stisku tlačítka bude:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  NMHTTP1->Get("http://www.netmastersllc.com");
}
Spustíme aplikaci a stiskneme tlačítko. Stavový řádek je aktualizován podle přijatého dokumentu. Událost OnPacketRecvd aktualizuje stavový řádek, když data přijdou, zobrazením celkového počtu přenášených slabik a počtu slabik přijatých klientem.

Příklad 3
Opět začneme novou aplikací. Na formulář umístíme komponenty TStatusBar, TButton, 3x TEdit a TNMSMTP a nastavíme vlastnost SimplePanel stavového řádku na true.
Vytvoříme obsluhu události OnPacketSent komponenty TNMSMTP s tímto obsahem:
void __fastcall TForm1::NMSMTP1PacketSent(TObject *Sender)
{
  StatusBar1->SimpleText = IntToStr(NMSMTP1->BytesSent)+
        " bytes out of "+IntToStr(NMSMTP1->BytesTotal)+" transferred";
}
Obsluha OnConnect komponenty TNMSMTP bude vypadat takto:
void __fastcall TForm1::NMSMTP1Connect(TObject *Sender)
{
  NMSMTP1->SendMail();
}
Pokuste se sami vytvořit obsluhu události OnSuccess komponenty TNMSMTP informující na stavovém řádku o úspěšnosti operace. Dále vytvoříme obsluhu stisku tlačítka s tímto obsahem:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  int I;
  NMSMTP1->Host = Edit1->Text;
  NMSMTP1->UserID = Edit2->Text;
  NMSMTP1->PostMessage->FromAddress = Edit3->Text;
  NMSMTP1->PostMessage->ToAddress->Text = Edit3->Text;
  NMSMTP1->PostMessage->Subject = "Testing BytesSent";
  for (I = 1; I <= 10; I++)
    NMSMTP1->PostMessage->Body->Add("Test line "+IntToStr(I));
  NMSMTP1->Connect();
}
Spustíme aplikaci. Do Edit1 zapíšeme jméno nebo IP adresu našeho SMTP serveru. Do Edit2 zapíšeme ID uživatele pro SMTP server. Do Edit3 zapíšeme naši e-mail adresu. Když stiskneme tlačítko, pak si sami sobě zašleme mail a když paket je odeslán (v tomto případě je pouze jeden), pak stavový řádek zobrazuje počet odeslaných slabik.

Příklad 4
Začneme opět novou aplikaci. Na formulář umístíme 2x TButton, TNMSMTP, 3x TEdit a TMemo. Obsluha stisku prvního tlačítka bude tvořena:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  NMSMTP1->Host = Edit1->Text;
  NMSMTP1->UserID = Edit2->Text;
  NMSMTP1->PostMessage->ToAddress->Text = Edit3->Text;
  NMSMTP1->PostMessage->FromAddress = Edit3->Text;
  NMSMTP1->PostMessage->Subject = "Test message";
  NMSMTP1->PostMessage->Body->Add("This is a test message");
  NMSMTP1->PostMessage->Body->Add
    ("If this message is delivered, the Cancel button (Button2) wasn't pressed fast enough");
  NMSMTP1->Connect();
}
Obsluha OnConnect komponenty TNMSMTP je tvořena:
void __fastcall TForm1::NMSMTP1Connect(TObject *Sender)
{
  Memo1->Lines->Add("Connected, sending message");
  NMSMTP1->SendMail();
}
a obsluhu OnSuccess stejné komponenty tvoří:
void __fastcall TForm1::NMSMTP1Success(TObject *Sender)
{
  Memo1->Lines->Add("Success, you didn't press Button2 fast enough");
  if (NMSMTP1->Connected)
    NMSMTP1->Disconnect();
}
Obsluhu stisku druhého tlačítka tvoří kód:
void __fastcall TForm1::Button2Click(TObject *Sender)
{
  Powersock1->Cancel();
}
Zbývá ještě vytvořit obsluhu události OnDisconnect komponenty TNMSMTP:
void __fastcall TForm1::NMSMTP1Disconnect(TObject *Sender)
{
  Memo1->Lines->Add("Disconnected");
}
Spustíme aplikaci. Do Edit3 zapíšeme naši e-mail adresu. Zapíšeme jméno hostitele nebo IP adresu našeho SMTP serveru do Edit1. Pokud při přihlašování k našemu SMTP serveru je požadováno ID uživatele, pak je zadáme do Edit2 (nebo jej ponecháme prázdný).
Nyní stiskneme první tlačítko. Když v Memo se objeví Connected, sending message, pak stiskneme druhé tlačítko. Po jeho stisku je generována výjimka a je volána obsluha OnDisconnect, která oznamuje uživateli odpojení.
Pokud druhé tlačítko nestiskneme před úspěšným odesláním zprávy, pak obsluha OnSuccess přidá do Memo oznámení, že uživatel tlačítko nestisknul a je volána metoda Disconnect k odpojení od vzdáleného hostitele, pokud klient je stále připojen (je oznámeno vlastností Connected).

Příklad 5
Dříve než můžeme použít událost OnRead, musíme:

V našem příkladě použijeme druhou možnost. Začneme vývoj nové aplikace. Na formulář umístíme TButton a TPowersock. Obsluhu stisku tlačítka bude tvořit:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  Powersock1->Host = "www.netmastersllc.com";
  Powersock1->Port = 13;
  Powersock1->ReportLevel = 1;
  Powersock1->TimeOut = 5000;
  Powersock1->Connect();
}
Na konec souboru UNIT1.CPP zapíšeme následující kód:
// Tato metoda bude přiřazena k události OnRead
void __fastcall TForm1::ReadEvent(TObject *Sender)
{
  ShowMessage(Powersock1->ReadLn());
}
void __fastcall TForm1::FormCreate(TObject *Sender)
{
  Powersock1->OnRead = ReadEvent;
}
Přidáme metodu ReadEvent k definici třídy formuláře do hlavičkového souboru takto:
class TForm1 : public TForm
{
__published: // IDE-managed Components
    TButton *Button1;
    TPowersock *Powersock1;
    void __fastcall Button1Click(TObject *Sender);
    void __fastcall FormCreate(TObject *Sender);
private: // User declarations
public:  // User declarations
    __fastcall TForm1(TComponent* Owner);
    void __fastcall ReadEvent(TObject *Sender);
};
Když stiskneme tlačítko, pak vlastnost TimeOut je nastavena na 5000 (5 sekund) a tak v případě chybného hostitele nebo chybějící reakce v uvedeném čase, pokus o připojení ukončí. Vlastnost ReportLevel je nastavena na 1 a tak budou zasílány pouze základní informační zprávy. Je zřízeno připojení na specifikovaného hostitele, v našem případě na www.netmastersllc.com,  port 13. Port 13 je standardním portem pro protokol DayTime. Když vzdálený hostitel zašle datum a čas, nastane událost OnRead, která zobrazí datum a čas pomocí ShowMessage.

Komponenta TNMGeneralServer

Komponenta TNMGeneralServer je poskytnuta pro použití jako základní třída pro vývoj vícevláknových Internetovských serverů (zákaznických serverů nebo serverů podporujících standard RFC). Komponenta TNMGeneralServer není určena k použití jako samostatná komponenta, i když takto může být použita. Komponenta je odvozena od TPowersock.
Vytvářením potomků třídy TNMGeneralServer a přepisováním metody Serve, můžeme přizpůsobit reagování serveru na klientské připojení. Interakce s klientem je prováděna pomocí čtecích a zápisových metod zděděných od TPowersock.
Poznámka: Vlastnost Port musí být nastavena během návrhu.

Metoda Serve je virtuální metoda, která ve třídách potomků bývá předefinována. Metoda Serve je metoda, která je volána vždy, když se klient připojí na server. Metoda Serve je prováděna v jiném vlákně a tak objekty a metody VCL nemohou být použity v této metodě.
Poznámka: Metoda Serve nedělá nic, když je volána přímo ze třídy TNMGeneralServer. Musí být používána (přepsaná) ve třídách odvozených od TNMGeneralServer.
Když použijeme metodu Serve v odvozené třídě, pak musíme volat zděděnou metodu Serve. Když metoda Serve skončí, pak klient je odpojen od serveru.
Událost
property OnClientContact: TNotifyEvent;
nastává vždy, když klient se připojuje na server.

Funkce NthPos

Funkce vrací pozici specifikovaného výskytu specifikovaného oddělovače v řetězci. První parametr obsahuje rozkládaný řetězec, druhý parametr určuje znak použitý jako oddělovač a třetí parametr určuje kolikátý oddělovač hledáme.
Poznámka: Použití této funkce nevyžaduje použít nějakou komponentu FastNet v aplikaci, postačuje aby hlavičkový soubor Psock.hpp byl vložen do jednotky používající tuto funkci.
S použitím se seznámíme na příkladě. Začneme vývoj nové aplikace a na formulář vložíme tlačítko a čtyři editační ovladače. Do jednotky za řádek
#include <Forms.hpp>
vložíme:
#include <Psock.hpp>
Vytvoříme obsluhu stisku tlačítka:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  Edit4->Text = IntToStr(NthPos(Edit1->Text, Edit2->Text[1],
     StrToIntDef(Edit3->Text,2)));
}
Po spuštění aplikace do prvního editačního ovladače zapíšeme prohledávaný řetězec. Vložíme sem např. This*is*very*informative. Do druhého editačního ovladače zapíšeme oddělovač. V našem případě použijeme *. Do třetího editačního ovladače zapíšeme kolikátý výskyt hvězdičky hledáme (zapíšeme např. 3). Po stisku tlačítka se pozice hledaného oddělovače zobrazí v posledním editačním ovladači.

Funkce NthWord

Funkce vrací slovo z řetězce. První parametr specifikuje prohledávaný řetězec, druhý parametr specifikuje znak oddělující slova a třetí parametr určuje kolikáté slovo má být vráceno.
Poznámka: Použití této funkce nevyžaduje použít nějakou komponentu FastNet v aplikaci, postačuje aby hlavičkový soubor Psock.hpp byl vložen do jednotky používající tuto funkci.

Funkce StreamLn

Metoda přidává řetězec do proudu. První parametr specifikuje proud, ke kterému přidáváme řetězec a druhý parametr specifikuje přidávaný řetězec.
Poznámka: Použití této funkce nevyžaduje použít nějakou komponentu FastNet v aplikaci, postačuje aby hlavičkový soubor Psock.hpp byl vložen do jednotky používající tuto funkci.

Komponenta TNMDayTime

Komponenta je používána pro získávání datumu a času ze služby daytime Internetu, jak je popsáno v RFC 867. Komponenta je odvozena od TPowersock. Vyžaduje WSOCK32.DLL.
Dříve než můžeme získat datum a čas z internetovské služby daytime, musíme nejprve znát jméno hostitele nebo tečkovou IP adresu hostitele datumu a času a přiřadit tuto hodnotu vlastnosti Host.
Po nastavení Host pouze čteme hodnotu vlastnosti DayTimeStr, čímž získáme datum a čas od specifikovaného hostitele.
 
property DayTimeStr: string; Vlastnost obsahuje datum a čas získané od vzdáleného hostitele. Formát datumu a času závisí na dotazovaném serveru. Public RunTime, ReadOnly

Pozor: Volání zděděné metody Connect způsobí chybu.


Komponenta TNMEcho

Komponenta je používána k zasílání textu na Internetovskou službu echo a opětovně očekává přijetí tohoto textu, jak je popsáno v RFC 862. Je často používána pro testování integrity a přenosové rychlosti sítě. Před odesláním textu na server musí být zřízeno propojení. Zřízení propojení je dokončeno nastavením vlastnosti Host na přípustný internetovský server echo a vlastnost Port na odpovídající port. Server Echo obvykle naslouchá na portu 7. Odeslání textu na server je provedeno metodou Echo.
 
property ElapsedTime: single; Vlastnost určuje čas potřebný k vrácení zaslaného textu zpět klientovi. Public RunTime, ReadOnly

Poznámka:  Toto vlastnost není nastavena dokud metoda Echo není volána, a obsahuje výsledek z posledního volání.

function Echo(EchoString: string): string;
Metoda zasílá text předaný v parametru na vzdálený server. Tento text je vracen zpět a tvoří návratovou hodnotu metody (k původnímu textu je připojeno odřádkování).
Poznámka: Před voláním této metody musíme být připojeni na vzdáleného hostitele. Pokud nejsme připojeni vzniká událost OnConnectionRequired.


Komponenta TNMFinger

Komponenta je používána k získávání informací o uživateli z Internetovského serveru finger, pomocí protokolu Finger popsaného v RFC 1288.
Dříve než můžeme získat informace o uživateli z vlastnosti FingerStr, musíme nastavit vlastnost Host na existující server Finger. Vlastnost Port normálně není nutno měnit, neboť většina serverů Finger naslouchá na portu 79.
 
property FingerStr: string; Vlastnost obsahuje informaci (je-li) o specifikovaném uživateli. Public RunTime, ReadOnly
property User: string; Vlastnost specifikuje uživatele k získání informací o něm. Published DesignTime, RunTime

Poznámka: Pokud server nenalezne informaci o uživateli, pak vlastnost FingerStr obsahuje User Not Found.
Varování: Vlastnost Host musí být nastavena na přípustný server Finger a vlastnost User musí být nastavena před přístupem ve vlastnosti FingerStr.


Jednotka NMFtp

Jednotka TNMFTP obsahuje komponentu TNMFTP a typy a třídy, které využívá. Jsou zde třídy: a typy:

Třída TFTPDirectoryList

Třída je základní třídou pro všechny ostatní rozkládající třídy adresářových seznamů FTP. Pokud nalezneme hostitele FTP, který neodpovídá některému ze současně dostupných předdefinovaných objektů, pak od této třídy můžeme odvodit svůj vlastní rozkladač seznamu.
Všechny vlastnosti této třídy jsou typu TStringList. Indexy každé vlastnosti odpovídají stejnému indexu v každé ostatní vlastnosti. name[1] a Attribute[1] obsahují jméno a tributy pro druhý (indexy začínají od 0) prvek v seznamu. Jsou zde tyto vlastnosti: Třída má dvě metody:

procedure Clear;
Metoda vyprazdňuje vlastnosti objektu seznamu. Po jejím volání, každý objekt TStringList je prázdný.

procedure ParseLine(Line: string); virtual;
Metoda rozkládá řádek seznamu a odděluje jména, velikosti, datum modifikace a atributy souboru do jejich samostatných vlastností v objektu.

Typ TCmdType

TCmdType = (cmdChangeDir, cmdMakeDir, cmdDelete, cmdRemoveDir, cmdList,
  cmdRename, cmdUpRestore, cmdDownRestore, cmdDownload, cmdUpload,
  cmdAppend, cmdReInit, cmdAllocate, cmdNList, cmdDoCommand, cmdCurrentDir);
Typ poskytuje jednoduchý způsob odkazování se na dostupné příkazy komponenty TNMFTP. Výčtový typ uvádí jednotlivé příkazy FTP.

Typ TFailureEvent

TFailureEvent = procedure(var Handled: Boolean; Trans_Type: TCmdType)
   of object;
Typ je používán pro událost OnFailure. Parametr Handled určuje zda implicitní akce byla provedena nebo ne. Parametr Trans_Type specifikuje chybující příkaz.

Typ TNMListItem

TNMListItem = procedure(Listing: string) of object;
Typ události je použit pro předávání prvků řetězce po jednom události. To je užitečné v události OnListItem, která vrací seznam z metod List a NList. Parametr Listing obsahuje současný prvek, který má být předán.

Typ TSuccessEvent

TSuccessEvent = procedure(Trans_Type: TCmdType) of object;
Typ události je použit událostí OnSuccess, když příkaz je proveden úspěšně. Parametr specifikuje příkaz, který byl proveden úspěšně.

Typ TUnsupportedEvent

TUnsupportedEvent = procedure(Trans_Type: TCmdType) of object;
Typ události TUnsupportedEvent je použit v události OnUnSupportedFunction. To předává nepodporovaný příkaz.

Komponenta TNMFTP

Význam komponenty TNMFTP je pro přenášení souborů na  a z Internet/Intranet FTP server prostřednictvím protokolu FTP popsaného v RFC 959. Použití této komponenty vyžaduje WSOCK32.DLL, který může být získán od různých dodavatelů.
Dříve než můžeme použít komponentu TNMFTP pro přenos souborů na nebo ze vzdáleného hostitele, se musíme připojit. To je zajištěno nastavením vlastností Host a Port na přípustný FTP server. Pak nastavíme vlastnosti UserID a Password na identifikaci a heslo uživatele tohoto serveru. Mnoho serverů akceptuje Anonymous jako identifikaci uživatele a naši e-mail adresu jako heslo. Po nastavení těchto vlastností voláme metodu Connect pro připojení na server.
Když již jsme připojeni na server, pak můžeme získat seznam souborů a adresářů voláním metody List a zápisem obsluhy události pro událost OnListItem. Můžeme změnit současný adresář (nazývaný "pracovní" adresář) voláním metody ChangeDir, specifikující přípustné jméno nového pracovního adresáře.
Uložení souborů do současného adresáře na vzdáleném hostiteli provedeme voláním metody Upload. Metoda Upload přebírá jméno souboru na našem lokálním počítači a jméno k uložení na vzdáleném počítači jako parametr. Nemůžeme ukládat soubory na hostitele FTP, pokud k tomu nemáme potřebná práva. To je často povoleno v adresáři nazvaném incoming. Pokud soubor existuje na serveru pod stejným jménem jako je specifikováno v metodě Upload, pak soubor je přepsán.
K natažení souborů ze vzdáleného hostitele, nejdříve voláme metodu List k zjištění dostupných souborů ke stažení. Pak voláme metodu Download, s předáním jména souboru, který chceme stáhnout a cesty a jména k uložení na našem počítači jako parametrů. Obecně, můžeme mít umožněno stahovat soubory z adresáře nazvaného pub. Pokud soubor se stejným jménem existuje na našem počítači, pak je přepsán.
K vytvoření adresáře na vzdáleném hostiteli musíme mít příslušná práva. Obecně bývá povoleno vytvářet podadresáře v adresáři incoming na hostiteli FTP. K vytvoření adresáře voláme MakeDirectory a předáme jméno vytvářeného adresáře jako parametr.
K odstranění adresáře ze vzdáleného hostitele musíme mít příslušná práva. Pokud je máme, pak voláme metodu RemoveDir, které předáme jméno rušeného adresáře jako parametr.
Komponenta má následující vlastnosti:
 
property CurrentDir: string; Vlastnost obsahuje jméno současného adresáře na vzdáleném systému. Po volání ChangeDir se může změnit. Public RunTime, ReadOnly
property FTPDirectoryList: TFTPDirectoryList; Vlastnost je používána pouze pokud vlastnost ParseList je nastavena na true. FTPDirecxtoryList obsahuje seznam získaný z metody List, kde jednotlivé prvky jsou rozděleny do vlastností.
property ParseList: boolean; Vlastnost určuje zda rozkládat adresářový seznam do vlastnosti FTPDirectoryList nebo ne. Při nastavení na false, adresářový seznam rozkládán není a musí být zpracováván událostí OnListItem. Published Runtime, Designtime
property Password: string; Vlastnost specifikuje heslo použité při přihlašování na vzdáleného hostitele FTP. Pokud specifikované heslo je chybné, pak je generována událost OnAuthenticationFailed. Když heslo není zadáno vzniká událost OnAuthenticationNeeded. Published Runtime, Designtime
property UserID: string; Vlastnost specifikuje ID uživatele použité při přihlašování na vzdáleného hostitele FTP. Published Runtime, designtime
property Vendor: integer; Vlastnost specifikuje typ hostitele FTP, ke kterému se připojujeme. To umožňuje rozložit adresářový seznam hostitele správným způsobem. Implicitní hodnota: NMOS_AUTO. Možné hodnoty jsou: NMOS_UNIX, NMOS_WINDOWS, NMOS_VM, NMOS_BULL, NMOS_MAC, NMOS_TOPS20, NMOS_VMS, NMOS_OS2, NMOS_MVS_IBM, NMOS_MVS_INTERLINK, NMOS_OTHER, NMOS_AUTO, NMOS_NT, NMOS_TANDEM, NMOS_AS400, NMOS_OS9 a NMOS_NETWARE.

Komponenta má následující metody:

procedure Allocate(FileSize: Integer);
Metoda se používá pro alokování místa na vzdáleném hostiteli pro ukládaný soubor. Parametr specifikuje počet alokovaných slabik pro přicházející soubor. Tato metoda není požadována často. Poskytuje podporu pro servery, které vyžadují alokování diskového prostoru dříve než ukládání souboru může být provedeno.

procedure ChangeDir(DirName: string);
Metoda mění aktuální adresář na vzdáleném hostiteli. Parametr specifikuje jméno nového aktuálního adresáře. Může to být adresář umístěný v aktuálním adresáři nebo úplná cesta. Při změně adresáře se změní i vlastnost CurrentDir. Pokud příkaz je úspěšný, pak je generována událost OnSuccess, jinak událost OnFailure. V obou případech jako parametr Trans_Type události je předáno cmdChangeDir.

procedure Delete(Filename: string);
Metoda ruší soubor ze vzdáleného hostitele. Parametr specifikuje rušený soubor na vzdáleném hostiteli. Může to být soubor v současném pracovním adresáři nebo adresářová cesta se jménem souboru někde na vzdáleném systému. Pro rušení souboru musíme mít zápisová privilegia. Pokud příkaz je úspěšný, pak je generována událost OnSuccess, jinak událost OnFailure. V obou případech jako parametr Trans_Type události je předáno cmdDelete.

procedure DoCommand(CommandStr: string);
Metoda se používá pro zasílání příkazů na vzdáleného hostitele FTP. Tato metoda je užitečná pro použití s uživatelskými hostiteli FTP, které mají nestandardní příkazy nebo pro podporu neimplementovaných příkazů. Parametr je příkaz, který bude odeslán na server. Může být jednoduchý jako pwd (příkaz pro získání jména aktuálního adresáře) nebo složité jako zavádění více souborů.

procedure Download(RemoteFile, LocalFile: string);
Metoda je používána pro zavádění souborů ze vzdáleného hostitele FTP na lokální počítač. Parametr RemoteFile specifikuje jméno souboru v současném pracovním adresáři na vzdáleném hostiteli k zavedení. Parametr LocalFile specifikuje jméno pod kterým soubor má být uložen na lokálním počítači. Pokud soubor se stejným jménem již existuje, pak je přepsán. Pokud příkaz je úspěšný, pak je generována událost OnSuccess, jinak událost OnFailure. V obou případech jako parametr Trans_Type události je předáno cmdDownload.

procedure DownloadRestore(RemoteFile, LocalFile: string);
Metoda zavádí soubor ze vzdáleného hostitele, pokračováním přenosu, který byl dříve přerušen. Parametr RemoteFile specifikuje jméno zaváděného vzdáleného souboru. Parametr LocalFile specifikuje jméno pro uložení souboru na lokální disk. Je to jméno souboru, který již existuje a je částí souboru dříve zaváděného. Tuto metodu nepodporují všechny hostitelé.

procedure List;
Metoda je používána pro získávání seznamu souborů a adresářů ze vzdáleného hostitele. Seznam je získáván ze současného pracovního adresáře. Pro každý uvedený prvek je generována událost OnListItem. Pokud ParseList je nastavena na true, pak vlastnost FTPDirectoryList obsahuje prvky obsažené v seznamu, včetně jmen, velikostí a atributů. Pokud příkaz je úspěšný, pak je generována událost OnSuccess, jinak událost OnFailure. V obou případech jako parametr Trans_Type události je předáno cmdList.

procedure MakeDirectory(DirectoryName: string);
Metoda vytváří adresář v současném pracovním adresáři na vzdáleném hostiteli FTP. Parametr specifikuje jméno vytvářeného adresáře. Může to být samotné jméno adresáře nebo úplná adresářová cesta. Pokud příkaz je úspěšný, pak je generována událost OnSuccess, jinak událost OnFailure. V obou případech jako parametr Trans_Type události je předáno cmdMakeDir.

procedure Mode(TheMode: Integer);
Metoda mění přenosový režim souboru použitý pro přenos souborů mezi vzdáleným hostitelem a lokálním počítačem. Parametr specifikuje přenosový režim. Jsou možné tyto hodnoty:

procedure Nlist;
Metoda je použita k získání seznamu pouze jmen souborů a adresářů ze současného pracovního adresáře. Pro každý získaný prvek je generována událost OnListItem. Pokud příkaz je úspěšný, pak je generována událost OnSuccess, jinak událost OnFailure. V obou případech jako parametr Trans_Type události je předáno cmdNList.

procedure Reinitialize;
Metoda je použita k opětovnému nastavení připojení k serveru. To umožňuje připojení ke vzdálenému hostiteli před provedením autentizace (UserID a Password). Po volání metody Reinitialize je připojení v nepoužitelném stavu. Před prováděním budoucích FTP transakcí, musíme opětovně zaslat identifikaci uživatele a heslo. Jinak příkazy jsou neproveditelné.

procedure RemoveDir(DirectoryName: string);
Metoda je používána k odstraňování adresáře za vzdáleného hostitele FTP. Parametr specifikuje jméno odstraňovaného adresáře. Může to být jméno adresáře umístěného v současném pracovním adresáři nebo úplná adresářová cesta. Pokud příkaz je úspěšný, pak je generována událost OnSuccess, jinak událost OnFailure. V obou případech jako parametr Trans_Type události je předáno cmdRemoveDir.

procedure Rename(Filename, FileName2: string);
Metoda je používána pro přejmenování souboru v současném pracovním adresáři na vzdáleném hostiteli FTP. Parametr FileName specifikuje jméno přejmenovávaného souboru. Parametr FileName2 určuje nové jméno souboru. Tyto parametry mohou být jméno souboru v současném pracovním adresáři nebo cesta a jméno souboru umístěného kdekoliv v systému. Pokud příkaz je úspěšný, pak je generována událost OnSuccess, jinak událost OnFailure. V obou případech jako parametr Trans_Type události je předáno cmdRename.

procedure Upload(LocalFile, RemoteFile: string);
Metoda je používána pro odeslání souboru z lokálního počítače na vzdáleného hostitele. Parametr LocalFile specifikuje jméno souboru na lokálním počítači, který bude odeslán na vzdáleného hostitele. Parametr RemoteFile specifikuje jméno, které bude mít odeslaný soubor na vzdáleném hostiteli. Pokud soubor stejného jména již na vzdáleném hostiteli existuje, pak je přepsán. Pokud příkaz je úspěšný, pak je generována událost OnSuccess, jinak událost OnFailure. V obou případech jako parametr Trans_Type události je předáno cmdUpload.

procedure UploadAppend(LocalFile, RemoteFile: string);
Metoda je používána pro odeslání souboru z lokálního počítače na vzdáleného hostitele. Pokud soubor stejného jména již existuje, pak nový soubor je připojen na konec existujícího souboru. Parametr LocalFile specifikuje jméno souboru na lokálním počítači, který bude odeslán na vzdáleného hostitele. Parametr RemoteFile specifikuje jméno, které bude mít odeslaný soubor na vzdáleném hostiteli. Pokud příkaz je úspěšný, pak je generována událost OnSuccess, jinak událost OnFailure. V obou případech jako parametr Trans_Type události je předáno cmdAppend.

procedure UploadRestore(LocalFile, RemoteFile: string; Position: Integer);
Metoda je používána pro pokračování v odesílání souboru z lokálního počítače na vzdáleného hostitele FTP. Parametr LocalFile specifikuje jméno souboru na lokálním počítači, který bude odeslán na vzdáleného hostitele. Parametr RemoteFile specifikuje jméno, které bude mít odeslaný soubor na vzdáleném hostiteli. Při použití této metody soubor již musí na vzdáleném hostiteli existovat. Parametr Position specifikuje od jaké pozice soubor bude přenášen. Pokud příkaz je úspěšný, pak je generována událost OnSuccess, jinak událost OnFailure. V obou případech jako parametr Trans_Type události je předáno cmdAUpRestore.

procedure UploadUnique(LocalFile: string);
Metoda je používána pro odeslání souboru z lokálního počítače na vzdáleného hostitele. Jméno souboru na lokálním počítači je použito jako jméno souboru na vzdáleném hostiteli. Pokud soubor tohoto jména již existuje, pak pro soubor je použito unikátní jméno. Parametr LocalFile specifikuje jméno souboru na lokálním počítači, který bude odeslán na vzdáleného hostitele. Pokud příkaz je úspěšný, pak je generována událost OnSuccess, jinak událost OnFailure. V obou případech jako parametr Trans_Type události je předáno cmdAUpload.

Komponenta TNMFTP používá následující události:

property OnAuthenticationFailed: THandlerEvent;
Událost vzniká, když vlastnost UserID nebo vlastnost Password je nepřípustná. Pokud parametr Handled je nastaven na true, pak autentizace proběhne znova k dokončení přihlášení na vzdáleného hostitele. Pokud parametr Handled je false (implicitně), nebo pokud druhý pokus o přihlášení je neúspěšný, pak je generována výjimka.

property OnAuthenticationNeeded: THandlerEvent;
Vlastnost vzniká, když události UserID a Password jsou prázdné. Pokud parametr Handled je false, pak je generována výjimka. Jestliže Handled nastavíme na true a poskytneme UserID a/nebo Password, pak autentizace proběhne znova. Pokud podruhé je neúspěšná, pak je generována výjimka a připojení je zrušeno. Tato událost obvykle nastává, když je volána metoda Connect a identifikace uživatele nebo heslo není zadáno.

property OnFailure: TFailureEvent;
Událost je generována, pokud prováděný FTP příkaz je neúspěšný. Pokud parametr Handled je nastaven na true, pak výjimka není generována. Má-li hodnotu false, pak bude výjimka generována podruhé k chybujícímu příkazu. Parametr Trans_Type specifikuje chybující příkaz.

property OnListItem: TNMListItem;
Událost je generována pro každý prvek při rozkládání seznamu souborů. Událost je generována metodami List a NList.

property OnSuccess: TSuccessEvent;
Událost je generována, když příkaz je úspěšně dokončen. Parametr Trans_Type specifikuje dokončený příkaz.

property OnTransactionStart: TNotifyEvent;
Událost je generována vždy, když data jsou odesílána ze vzdáleného hostitele na lokální počítač pomocí datového soketu. Tuto událost generují následující metody: List, Download, UploadUnique, Upload, NList, DownloadRestore, UploadAppend a UploadRestore.

property OnTransactionStop: TNotifyEvent;
Událost je generována vždy, když přenos dat ze vzdáleného hostitele na lokální počítač je dokončen. Tuto událost generují následující metody: List, Download, UploadUnique, Upload, NList, DownloadRestore, UploadAppend a UploadRestore.

property OnUnSupportedFunction: TUnsupportedEvent;
Tato událost nastává, když prováděný příkaz FTP je neúspěšný, protože na vzdáleném hostiteli není implementován. Parametr Trans_Type specifikuje tento příkaz.


Komponenta TNMURL

Významem komponenty TNMURL je zakódovat řetězec formátu URL pro přenosy HTTP a dekódovat data URL do čitelných řetězců. Tato komponenta není odvozena od TPowersock, ale od TComponent.
Použití komponenty je snadné. Jednoduše nastavíme vlastnost InputString a potom vlastnost Encode bude obsahovat zakódovaný řetězec URL a vlastnost Decode bude obsahovat dekódovaný řetězec. Pokud nastane chyba, pak vznikne událost OnError.
Komponenta má následující vlastnosti:
 
property Decode: String; Vlastnost obsahuje dekódovaný řetězec, na základě zakódovaného řetězce ve vlastnosti InputString. Pokud InputString není zakódované URL, pak Decode je stejné jako InputString. Public RunTime, ReadOnly
property Encode: String; Vlastnost obsahuje zakódovanou kopii URL z vlastnosti InputString. Public RunTime, ReadOnly
property InputString: String; Vlastnost obsahuje zakódovaná data k dekódování nebo standardní řetězec k zakódování.

  1. Použití komponenty TNMDayTime si ukážeme na příkladě. Začneme vývoj nové aplikace. Na formulář umístíme tlačítko, TLabel a TNMDayTime. Obsluhu stisku tlačítka budou tvořit příkazy:

  2. void __fastcall TForm1::Button1Click(TObject *Sender)
    {
      NMDayTime1->ReportLevel = Status_Basic;
      NMDayTime1->TimeOut = 5000;
      NMDayTime1->Host = "www.netmastersllc.com";
      Label1->Caption = NMDayTime1->DayTimeStr;
    }
    V tomto příkladě vlastnost ReportLevel je nastavena na Status_Basic, pro oznamování základního stavu. Vlastnost TimeOut je nastavena na 5000. Vlastnost Host je nastavena na www.netmastersllc.com, kde je spuštěna služba DayTime. Získaný datum a čas je zobrazen v komponentě TLabel.
  3. Již hotovou aplikaci používající komponentu TNMDayTime nalezneme v adresáři Program Files\Borland\CBuilder\Examples\Interner\DayTime. Prohlédněte si tuto aplikaci a snažte se pochopit, jak pracuje.
  4. Zahájíme vývoj nové aplikace a na formulář vložíme TEdit, 2x TLabel, 3x TButton a TNMEcho. Obsluha stisku prvního tlačítka je tvořena příkazem:

  5. void __fastcall TForm1::Button1Click(TObject *Sender)
    {
      NMEcho1->Host = "www.netmastersllc.com";
      NMEcho1->Connect();
    }
    Obsluhu stisku druhého tlačítka tvoří:
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
      NMEcho1->Disconnect();
    }
    a obsluha stisku třetího tlačítka:
    void __fastcall TForm1::Button3Click(TObject *Sender)
    {
      Label1->Caption = NMEcho1->Echo(Edit1->Text);
      Label2->Caption = FloatToStr(NMEcho1->ElapsedTime);
    }
    Po spuštění aplikace stiskem prvního tlačítka se připojíme ke vzdálenému hostiteli (našem případě k www.netmastersllc.com). Druhé tlačítko používáme k odpojení od vzdáleného hostitele po ukončení práce. Třetí tlačítko odešle text z editačního ovladače a vrácený text je zobrazen v Label1. Label2 obsahuje kolik času (v milisekundách) uplynulo do vrácení dat.
  6. Již hotovou aplikaci používající komponentu TNMEcho nalezneme v adresáři Program Files\Borland\CBuilder\Examples\Interner\Echo. Prohlédněte si tuto aplikaci a snažte se pochopit, jak pracuje.
  7. Použití TNMFinger si ukážeme na příkladě, kde na formulář umístíme TButton, TMemo a TNMFinger. Obsluhu tlačítka tvoří:

  8. void __fastcall TForm1::Button1Click(TObject *Sender)
    {
      NMFinger1->User = "netmasters";
      NMFinger1->Host = "inc-net.com";
      Memo1->Text = NMFinger1->FingerStr;
    }
    Když ve spuštěné aplikaci stiskneme tlačítko, pak vlastnost User je nastavena na NetMasters, uživatele pro kterého hledáme informace. Host je nastaven na inc-net.com, kde můžeme nalézt tyto informace. Získané informace jsou zobrazeny v Memo1.
  9. Již hotovou aplikaci používající komponentu TNMFinger nalezneme v adresáři Program Files\Borland\CBuilder\Examples\Interner\Finger. Prohlédněte si tuto aplikaci a snažte se pochopit, jak pracuje.
  10. Použití komponenty TNMFTP si ukážeme na příkladě. Začneme novou aplikací a na formulář umístíme 3x TEdit, 10x TButton, TMemo, TStringGrid, TStatusBar a TNMFTP. Význam komponent je tento:
  11. Obsluha stisku prvního tlačítka bude tvořena příkazy:
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
      if (NMFTP1->Connected)
        NMFTP1->Disconnect();
      else
        {
          NMFTP1->Vendor = NMOS_AUTO;
          NMFTP1->Host = Edit1->Text;
          NMFTP1->UserID = Edit2->Text;
          NMFTP1->Password = Edit3->Text;
          NMFTP1->Connect();
        }
    }
    Při stisku prvního tlačítka, pokud připojení je již zřízeno, pak metoda Disconnect je použita k uzavření připojení. Pokud připojení zatím zřízeno není, pak vlastnost Vendor je nastavena na NMOS_AUTO, což způsobuje autodetekci dodavatele FTP (je-li to možné). Vlastnost Host je nastavena na jméno hostitele nebo jeho IP adresu zadanou v Edit1. Vlastnost UserID je nastavena na jméno uživatele zadané v Edit2. Vlastnost Password je nastavena na hodnotu z Edit3 a metodou Connect je zřízeno připojení.
    Obsluha stisku druhého tlačítka je:
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
      NMFTP1->List();
    }
    Při stisku tlačítka je provedena metoda List k získání seznamu souborů a adresářů v aktuálním adresáři. Jelikož vlastnost ParseList byla nastavena na true, adresářový seznam je rozložen a umístěn do položek vlastnosti FTPDirectoryList.
    Obsluha stisku třetího tlačítka je tvořena příkazem:
    void __fastcall TForm1::Button3Click(TObject *Sender)
    {
      AnsiString TheDir;
      if (InputQuery("Change Directory", "Which directory?", TheDir))
        NMFTP1->ChangeDir(TheDir);
    }
    Při stisku tlačítka funkce InputQuery je použita k získání jména adresáře. Když stiskneme tlačítko OK, pak metoda ChangeDir se pokusí změnit aktuální adresář na specifikovaný adresář.
    Obsluha stisku čtvrtého tlačítka je tvořena příkazem (podobá se předchozí obsluze):
    void __fastcall TForm1::Button4Click(TObject *Sender)
    {
      AnsiString TheDir;
      if (InputQuery("Make Directory", "Directory name?", TheDir))
        NMFTP1->MakeDirectory(TheDir);
    }
    Obsluhy stisku pátého a šestého tlačítka jsou opět podobné:
    void __fastcall TForm1::Button5Click(TObject *Sender)
    {
      AnsiString TheDir;
      if (InputQuery("Remove Directory", "Directory name?", TheDir))
        NMFTP1->RemoveDir(TheDir);
    }
    void __fastcall TForm1::Button6Click(TObject *Sender)
    {
      AnsiString TheFile;
      if (InputQuery("Delete File", "File name?", TheFile))
        NMFTP1->Delete(TheFile);
    }
    Obsluhu sedmého tlačítka tvoří:
    void __fastcall TForm1::Button7Click(TObject *Sender)
    {
      AnsiString OldFile, NewFile;
      if (InputQuery("Rename file", "File to rename?", OldFile))
        if (InputQuery("Rename file", "New file name?", NewFile))
          NMFTP1->Rename(OldFile, NewFile);
    }
    Zde je funkce InputQuery volána dvakrát. Poprvé zadáváme jméno přejmenovávaného souboru a podruhé nové jméno souboru.
    Obsluha stisku osmého tlačítka je tvořena příkazy:
    void __fastcall TForm1::Button8Click(TObject *Sender)
    {
      ShowMessage("After reinitilizing, you must click the authenticate button");
      NMFTP1->Reinitialize();
    }
    Funkce ShowMessage je použita k zobrazení varování, že po reinicializaci je požadována autentizace. Obsluha stisku dalšího tlačítka je tvořena příkazy:
    void __fastcall TForm1::Button9Click(TObject *Sender)
    {
      AnsiString AnID, APass;
      if (InputQuery("Authentication needed", "Enter User ID", AnID))
        if (InputQuery("Authentication needed", "Enter Password", APass))
          {
            NMFTP1->DoCommand("USER "+AnID);
            NMFTP1->DoCommand("PASS "+APass);
          }
    }
    Zde funkce InputQuery je opět volána dvakrát. Prvním voláním získáme identifikaci uživatele a podruhé heslo. Dále je metoda DoCommand použita k odeslání příkazu USER a příkazu PASS na vzdáleného hostitele, čímž se přihlásíme k hostiteli. Toto je jediná možnost pokračování sezení FTP po volání metody Reinitialize.
    Obsluha stisku posledního tlačítka je tvoře příkazem:
    void __fastcall TForm1::Button10Click(TObject *Sender)
    {
      ShowMessage(NMFTP1->CurrentDir);
    }
    Zde pouze funkcí ShowMessage zobrazíme současný pracovní adresář na vzdáleném hostiteli.
    Následuje obsluha události OnAuthenticationFailed komponenty NMFTP1:
    void __fastcall TForm1::NMFTP1AuthenticationFailed(bool &Handled)
    {
      AnsiString ThePass, TheID;
      if (MessageDlg("Authentication Failed. Retry?", mtConfirmation,
        TMsgDlgButtons() << mbYes << mbNo, 0) == mrYes)
        {
          ThePass = NMFTP1->Password;
          TheID = NMFTP1->UserID;
          InputQuery("Reauthenticate", "Enter User ID", TheID);
          InputQuery("Reauthenticate", "Enter Password", ThePass);
          NMFTP1->Password = ThePass;
          NMFTP1->UserID = TheID;
          Handled = TRUE;
        }
    }
    Když autentizace na vzdáleném hostiteli je neúspěšná, pak prostřednictvím volání funkce InputQuery můžeme zadat novou hodnotu identifikace uživatele a hesla a nastavením Handled na true umožníme zopakování procesu autentizace.
    Obsluha události OnAuthenticationNeeded řeší nezadání identifikace uživatele nebo hesla a je tvořena příkazy:
    void __fastcall TForm1::NMFTP1AuthenticationNeeded(bool &Handled)
    {
      AnsiString APass, AnID;
      if (NMFTP1->Password == "")
        if (InputQuery("Password needed", "Enter password: ", APass))
          {
            NMFTP1->Password = APass;
            Handled = TRUE;
          }
        else
          Handled = FALSE;
      if (NMFTP1->UserID == "")
        if (InputQuery("User ID needed", "Enter User ID: ", AnID))
          {
            NMFTP1->UserID = AnID;
            Handled = TRUE;
          }
        else
          Handled = FALSE;
    }
    Obsluhy OnConnect a OnDisconnect jsou jednoduché:
    void __fastcall TForm1::NMFTP1Connect(TObject *Sender)
    {
      Memo1->Lines->Add("Connected");
      Button1->Caption = "Disconnect";
    }
    void __fastcall TForm1::NMFTP1Disconnect(TObject *Sender)
    {
      Memo1->Lines->Add("Disconnected");
      Button1->Caption = "Connect";
    }
    Obsluhu události OnFailure tvoří příkazy (do komponenty Memo je přidána informace o chybujícím příkazu):
    void __fastcall TForm1::NMFTP1Failure(bool &Handled, TCmdType Trans_Type)
    {
      switch(Trans_Type)
      {
        case cmdChangeDir: Memo1->Lines->Add("ChangeDir failed");
        case cmdMakeDir: Memo1->Lines->Add("MakeDir failed");
        case cmdDelete: Memo1->Lines->Add("Delete failed");
        case cmdRemoveDir: Memo1->Lines->Add("RemoveDir failed");
        case cmdList: Memo1->Lines->Add("List failed");
        case cmdRename: Memo1->Lines->Add("Rename failed");
        case cmdUpRestore: Memo1->Lines->Add("UploadRestore failed");
        case cmdDownRestore: Memo1->Lines->Add("DownloadRestore failed");
        case cmdDownload: Memo1->Lines->Add("Download failed");
        case cmdUpload: Memo1->Lines->Add("Upload failed");
        case cmdAppend: Memo1->Lines->Add("UploadAppend failed");
        case cmdReInit: Memo1->Lines->Add("Reinitialize failed");
        case cmdAllocate: Memo1->Lines->Add("Allocate failed");
        case cmdNList: Memo1->Lines->Add("NList failed");
        case cmdDoCommand: Memo1->Lines->Add("DoCommand failed");
        case cmdCurrentDir: Memo1->Lines->Add("CurrentDir failed");
      }
    }
    Následuje několik události informujících o počtu přenesených slabik a zahájení nebo ukončení práce:
    void __fastcall TForm1::NMFTP1PacketRecvd(TObject *Sender)
    {
      StatusBar1->SimpleText = "Received "+IntToStr(NMFTP1->BytesRecvd)+" bytes of
            "+IntToStr(NMFTP1->BytesTotal)+" total";
    }
    void __fastcall TForm1::NMFTP1PacketSent(TObject *Sender)
    {
      StatusBar1->SimpleText = "Sent "+IntToStr(NMFTP1->BytesSent)+" bytes of
            "+IntToStr(NMFTP1->BytesTotal)+" total";
    }
    void __fastcall TForm1::NMFTP1TransactionStart(TObject *Sender)
    {
      Memo1->Lines->Add("Data transfer start");
    }
    void __fastcall TForm1::NMFTP1TransactionStop(TObject *Sender)
    {
      Memo1->Lines->Add("Data transfer end");
    }
    Obsluhu události OnSuccess tvoří:
    void __fastcall TForm1::NMFTP1Success(TCmdType Trans_Type)
    {
      int I;
      switch(Trans_Type)
      {
        case cmdList:
        {
          for (I = 0; I <= (StringGrid1->ColCount - 1);I++)
            StringGrid1->Cols[I]->Clear();
          StringGrid1->RowCount = NMFTP1->FTPDirectoryList->name->Count;
          StringGrid1->ColCount = 4;
          StringGrid1->Cells[0][0] = "Filename";
          StringGrid1->Cells[1][0] = "File Size";
          StringGrid1->Cells[2][0] = "Modified Date";
          StringGrid1->Cells[3][0] = "Attributes";
          for (I = 0; I <= (NMFTP1->FTPDirectoryList->name->Count - 1); I++)
          {
            StringGrid1->Cells[0][I+1] = NMFTP1->FTPDirectoryList->name->Strings[I];
            StringGrid1->Cells[1][I+1] = NMFTP1->FTPDirectoryList->Size->Strings[I];
            StringGrid1->Cells[2][I+1] = NMFTP1->FTPDirectoryList->ModifDate->Strings[I];
            StringGrid1->Cells[3][I+1] = NMFTP1->FTPDirectoryList->Attribute->Strings[I];
          }
        }
        case cmdChangeDir:
        {
          Memo1->Lines->Add("ChangeDir successful");
          NMFTP1->List();
        }
        case cmdMakeDir: Memo1->Lines->Add("MakeDir successful");
        case cmdRemoveDir: Memo1->Lines->Add("RemoveDir successful");
        case cmdDelete: Memo1->Lines->Add("Delete successful");
        case cmdRename: Memo1->Lines->Add("Rename successful");
        case cmdReInit: Memo1->Lines->Add("Reinitialize successful");
        case cmdCurrentDir: Memo1->Lines->Add("CurrentDir successful");
      }
    }
    Poslední obsluhou události je OnUnSupportedFunction:
    void __fastcall TForm1::NMFTP1UnSupportedFunction(TCmdType Trans_Type)
    {
      switch(Trans_Type)
        {
          case cmdChangeDir: Memo1->Lines->Add("ChangeDir not supported by this server");
          case cmdMakeDir: Memo1->Lines->Add("MakeDir not supported by this server");
          case cmdDelete: Memo1->Lines->Add("Delete not supported by this server");
          case cmdRemoveDir: Memo1->Lines->Add("RemoveDir not supported by this server");
          case cmdList: Memo1->Lines->Add("List not supported by this server");
          case cmdRename: Memo1->Lines->Add("Rename not supported by this server");
          case cmdUpRestore: Memo1->Lines->Add("UploadRestore not supported by this server");
          case cmdDownRestore: Memo1->Lines->Add("DownloadRestore not supported by this server");
          case cmdDownload: Memo1->Lines->Add("Download not supported by this server");
          case cmdUpload: Memo1->Lines->Add("Upload not supported by this server");
          case cmdAppend: Memo1->Lines->Add("UploadAppend not supported by this server");
          case cmdReInit: Memo1->Lines->Add("Reinitialize not supported by this server");
          case cmdAllocate: Memo1->Lines->Add("Allocate not supported by this server");
          case cmdNList: Memo1->Lines->Add("NList not supported by this server");
          case cmdDoCommand: Memo1->Lines->Add("DoCommand not supported by this server");
          case cmdCurrentDir: Memo1->Lines->Add("CurrentDir not supported by this server");
      }
    }
    Tím je aplikace hotova a můžeme ji vyzkoušet.
  12. Již hotovou aplikaci používající komponentu TNMFTP nalezneme v adresáři Program Files\Borland\CBuilder\Examples\Interner\Ftp. Prohlédněte si tuto aplikaci a snažte se pochopit, jak pracuje.
  13. Začneme vývoj nové aplikace. Na formulář umístíme komponenty 2x TEdit, 2x TButton a TNMURL. Obsluha stisku prvního tlačítka je tvořena příkazy (dekódování):

  14. void __fastcall TForm1::Button1Click(TObject *Sender)
    {
      NMURL1->InputString = Edit1->Text;
      Edit2->Text = NMURL1->Encode;
    }
    Při stisku tlačítka je text z Edit1 uložen do vlastnosti InputString, je zakódován a uložen do Edit2. Obsluhu stisku druhého tlačítka tvoří:
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
      NMURL1->InputString = Edit1->Text;
      Edit2->Text = NMURL1->Decode;
    }
    Obsluha pracuje podobně jako předchozí obsluha, pouze místo zakódování provádí dekódování. Pro komponentu TNMURL vytvoříme ještě obsluhu OnError:
    void __fastcall TForm1::NMURL1Error(TObject *Sender,
         AnsiString Operation, AnsiString ErrMsg)
    {
      ShowMessage(Operation+": "+ErrMsg);
    }
    Chyba nastává, pokud zakódování nebo dekódování řetězce nelze provést. Obsluha chyby zobrazuje chybovou zprávu.
  15. Již hotovou aplikaci používající komponentu TNMURL nalezneme v adresáři Program Files\Borland\CBuilder\Examples\Interner\Url. Prohlédněte si tuto aplikaci a snažte se pochopit, jak pracuje.
11. Komponenty NetMasters I