Strona 1 z 1

Klient telnet

Nowy postNapisane: wtorek, 7 października 2008, 17:05
przez johny_be_bad
Witam,
piszę program w C++ Builder, którego jednym z zadań jest zalogowanie się na router (działa on pod kontrolą systemu Unix). Router pozwala na logowanie się przez telnet na porcie 23, proszac o login i haslo. Po zalogowaniu mozliwe jest wydawanie komend - tak jak w normalnym unixowym serwerze.
Program ma automatyzowac proces logowania i wydac kilka komend. Probowalem do polaczenia z routerem uzywac komponentu TClientSocket jednak nie nadaje sie on do tego celu. Cyfrowy Baron poradził abym zainteresował się bibliotekami INDY i napisał na tym forum - może ktoś Was robił coś podobnego? Zainstalowalem juz INDY, zaczalem zabawe z komponentem IdTelnet i popytalem google jak tego komponentu uzywac, najlepsze co znalazlem na temat, który mnie interesuje to http://delphi.newswhat.com/geoxml/forumhistorythread?groupname=borland.public.delphi.internet.winsock&messageid=463d2510@newsgroups.borland.com ale link ten dotyczy Delphi z którym nie miałem styczności - w skrócie: gość uznał że IdTelnet z INDY się nijak do tego celu nadaje i użył Synapse pod Delphi. Nie mogę użyć Delphi więc pytam czy ktoś z Was robil cos w tym rodzaju pod C++ Borland? Jeśli tak to prosze o wskazówki, linki, przykłady użycia w.w. komponentow.
Pozdrawiam

Re: Klient telnet

Nowy postNapisane: wtorek, 7 października 2008, 21:07
przez Darek_C++
johny_be_bad napisał(a):Probowalem do polaczenia z routerem uzywac komponentu TClientSocket jednak nie nadaje sie on do tego celu.
Nie nadaje się bo ? Łączysz się za pomocą socketów z hostem na porcie 23 następnie wysyłasz dane tekstowe jako komendy i odbierasz dane też tekstowe jakie serwer odsyła. Sesja telnet nie jest szyfrowana co dodatkowo ułatwia zadanie.

Re: Klient telnet

Nowy postNapisane: środa, 8 października 2008, 08:21
przez johny_be_bad
Kod: Zaznacz cały
ClientSocket1->Host="192.168.1.1";
ClientSocket1->Port=23;
ClientSocket1->Active=Enabled;
Memo1->Lines->Add(ClientSocket1->Socket->SendText("root\n"));
Memo1->Lines->Add(ClientSocket1->Socket->SendText("pass\n"));
Memo1->Lines->Add(ClientSocket1->Socket->ReceiveText());
Memo1->Lines->Add(ClientSocket1->Socket->ReceiveText());


racja, odbiera prosbe o haslo ale dopiero za drugim nacisnieciem buttona "˙ý˙ý˙ý!˙ű˙űunknown login: " za pierwszym zwraca dwa 0, dlaczego za drugim? żeby się zalogować muszę nacisnąć przycisk z przypisanym do niego powyższym kodem trzy razy. I tak bede musiał skorzystać z INDY (używam BCB Personal) przy wyświetlaniu w aplikacji stron ze statystykami pobieranych z routera...

Re: Klient telnet

Nowy postNapisane: środa, 8 października 2008, 13:57
przez Darek_C++
Znak kończący komendę powianiem być \r\n a nie \n

Komunikaty odbieraj w zdarzeniu:
Kod: Zaznacz cały
void __fastcall TForm1::ClientSocket1Read(TObject *Sender,
      TCustomWinSocket *Socket)
{
  Memo1->Lines->Add(Socket->ReceiveText());
}

Czasami nie wysyła się loginu i hasła razem ?
Kod: Zaznacz cały
ClientSocket1->Socket->SendText("root haslo\r\n");

Re: Klient telnet

Nowy postNapisane: środa, 8 października 2008, 16:48
przez johny_be_bad
OK, dzieki. Ale efekt jest ten sam (w memo procz wlasciwego teksu odbieranego od routera pojawiaja mi sie jakies wartosci i krzaczki).
Username i Password wysła się oddzielnie. Najpierw wysyłam jedno i oczekuje na odpowiedz serwera, potem drugie.
Rozdzieliłem łączenie i wysyłanie nazwy uzytkownika i hasla na dwa przyciski ale haslo jest wysylane za wczesnie (mimo, ze w dwoch komendach)
Jak moge ustawic czas oczekiwania na reakcje routera i jak pozbyc sie tych wartosci i krzaczkow (skad one sie biora)? nie ma jakiegos tutoriala dotyczacego uzytkowania tego komponentu?

Kod: Zaznacz cały
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ClientSocket1->Host="192.168.1.1";
ClientSocket1->Port=23;
ClientSocket1->Active=Enabled;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ClientSocket1Read(TObject *Sender,
      TCustomWinSocket *Socket)
{
Memo1->Lines->Add(Socket->ReceiveText());
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Memo1->Lines->Add(ClientSocket1->Socket->SendText("root\r\n"));
if(ClientSocket1->Socket->ReceiveText()=="Password:") Memo1->Lines->Add(ClientSocket1->Socket->SendText("password\r\n"));
}
//---------------------------------------------------------------------------

Re: Klient telnet

Nowy postNapisane: środa, 8 października 2008, 17:13
przez Darek_C++
Źle to obsługujesz! Zwrotne odpowiedzi serwera należy odczytywać w zdarzeniu ClientSocket1Read i w zależności od odesłanej odpowiedzi uruchamiać dalsze akcje już półautomatycznie np:
Kod: Zaznacz cały
void __fastcall TForm1::ClientSocket1Read(TObject *Sender,
      TCustomWinSocket *Socket)
{
    String odpowiedzi = Socket->ReceiveText().Trim();
    if(odpowiedzi.Pos("Password:")> 0 )
    {
        Memo1->Lines->Add(odpowiedzi);
        ClientSocket1->Socket->SendText("password\r\n");
    }
    // i dalej sprawdzasz jakie komendy sa odsylane
    // i reagujesz wysylajac walasne
}
Proces komunikacji przebiega liniowo tj. na komendy wysyłane przez klienta (Twoje) serwer wysyła odpowiedzi. Wiec cała sztuka polega na ich właściwym zgraniu ewentualnie dorobieniu obsługi błędów.

Re: Klient telnet

Nowy postNapisane: niedziela, 21 marca 2010, 08:54
przez Bert1223
Wyżej opisany sposób dotyczy socket, a co z IdTelnet w indy?
Jak tego używać? Znalazłem wpis na innym forum, że Indy 10 posiada SSH, nie wiem albo tego nie widzę albo tego nie ma.
Zależy mi na połączeniu się do router'a na linux i niezbędny do tego jest SSH. Znalazłem coś takiego http://www.libssh.org/2010/03/15/libssh-0-4-2/
Tylko nie wiem jak zainstalować to w codegear 2007?

Re: Klient telnet

Nowy postNapisane: niedziela, 21 marca 2010, 09:58
przez Bert1223
Co to telnetu to odpowiem sobie i innym czytającym ten wątek.

Do nawiązania połączenia przy pomocy Telnet potrzebne są dwa komponenty: IdTelnet i IdIOHandlerStack.
Dla atrybutu IOHandler w IdTelnet wskazałem na nasz komponent IdIOHandlerStack.
Dalej wystarczyło podać adres host'u i port domyślnie 23 w IdTelnet, dodatkowo wrzucamy 2 Memo

W zdarzeniu status dla IdIOHandlerStack
Kod: Zaznacz cały
Memo1->Lines->Add(AStatusText);

W zdarzenia status w IdTelnet
Kod: Zaznacz cały
Memo1->Lines->AddStrings(IdTelnet1->Greeting->Text);

W zdarzenia DataAvailable
Kod: Zaznacz cały
Memo2->Lines->Add(Buffer);

Na koniec dodajemy Edit i Button w zdarzeniu Click na Button
Kod: Zaznacz cały
IdTelnet1->IOHandler->WriteLn(Edit1->Text);