Avatar billede dittmer Nybegynder
22. juni 2003 - 00:21 Der er 27 kommentarer og
2 løsninger

Java-klient til terminal-dialog (telnet)

Hej,

Jeg skal bruge en Java-klient, der laver gennemfører en login-sekvens, men jeg kan ikke rigtig få skidtet til at virke.

\begin{kodestump}

System.out.println("Created socket"); //$NON-NLS-1$
           
StringBuffer received = new StringBuffer();
try {
    char c;
    while (input.ready() && (-1 != (c = (char) input.read()))) {
      received.append(c);
    }
    System.out.println(received);

    output.write(_username + "\n");
    System.out.println("Wrote username...");

    while (input.ready() && (-1 != (c = (char) input.read()))) {
      received.append(c);
    }
    System.out.println(received);
               
    System.out.println("done...");
} catch (IOException ioe) {
    System.err.println("Couldn't get I/O for the connection to: " + _loginHost); //$NON-NLS-1$
}

\end{kodestump}

I denne sekvens får jeg læst det korrekte ind i variablen received (i toppen af sekvensen), og programmet påstår, at det sender username (men jeg ved det faktisk ikke 100%).
Når jeg har afsendt username vil jeg gerne have en ny besked og handle efter den, men det lader ikke til, at der kommer noget tilbage. I hvert fald er variablen received tom, når jeg forsøger at skrive den ud...

Any ideas?


Mvh
Søren
Avatar billede swaq Nybegynder
22. juni 2003 - 00:29 #1
Avatar billede swaq Nybegynder
22. juni 2003 - 00:30 #2
Det er lidt svært at gennemskue hvad der kan være galt, hvad er input og output defineret som?
Avatar billede arne_v Ekspert
22. juni 2003 - 00:30 #3
Gæt:

Jeg tror at der sker det at den første read løkke læser prompten
for brugernavn korrekt men at fordi read er blocking venter den
på mere data og returnerer først -1 når serveren timer ud. Så udskriver
programmet korrekt prompten og sender brugernavn, men det er for sent.
Avatar billede arne_v Ekspert
22. juni 2003 - 00:32 #4
Hvis mit gæt er rigtigt så skal din første løkke terminere når
du har detected brugernavns prompten.

[det er jo også det der sker når man logger manuelt ind: når man
kan se prompten indtaster man brugernavn]
Avatar billede arne_v Ekspert
22. juni 2003 - 00:36 #5
Hvis du gerne vil se noget eksisterende kode så kig på:
  http://javassh.org/
Avatar billede dittmer Nybegynder
22. juni 2003 - 08:48 #6
Øhhh... JEg kan ikke se en hujende her... Er det kun mig, eller kan I heller ikke se teksten?
Avatar billede dittmer Nybegynder
22. juni 2003 - 08:54 #7
Okæh, der er klart noget i vejen. Jeg kan ikke se andet end min egen overskrift og så mit sidste indlæg. swaq og arne, jeg kan ikke se, hvad I har skrevet. Gider I skrive det igen?

Der er mange andre spørgsmål, jeg heller ikke kan se teksten på, men det seneste går fint... Weird...

Mvh
Søren
Avatar billede dsj Nybegynder
22. juni 2003 - 09:21 #8
Ja, jeg kan også se at arne_v kun har sagt tom luft :)
Avatar billede dittmer Nybegynder
22. juni 2003 - 10:15 #9
Mærkeligt - arne plejer da ikke at være fuld af varm luft... ;o)
Men han sover vist endnu...
Avatar billede arne_v Ekspert
22. juni 2003 - 11:07 #10
Eksperten har tilsyneladende lidt database problemer.
Avatar billede arne_v Ekspert
22. juni 2003 - 11:11 #11
Jeg kan heller ikke se spørgsmålet.

Men jeg kan huske lidt.

Min kommentar var et gæt på årsagen til problemet:

Du læser med read indtil du får -1. Jeg tror at du korrekt læser
prompten for brugernavn men at du venter på mere input
(read er blocking) indtil serveren timer ud og så returnerer
read -1. Derefter sender du brugernavn, men så er det jo for sent.

Og løsningen vil være kun at læse indtil du har læst prompten for brugernavm
og så sende brugernavnet. Det er jo også den måde det sker ved manuel
login. Man taster brugernavn ligeså snart der promptes for det.
Avatar billede arne_v Ekspert
22. juni 2003 - 11:12 #12
Og så henviste jeg til http://javassh.org/, hvor du måske kunne
låne lidt inspiration.
Avatar billede arne_v Ekspert
22. juni 2003 - 12:03 #13
OK - nu er alle indlægene tilbage.
Avatar billede dittmer Nybegynder
22. juni 2003 - 15:12 #14
swaq: input og output er erklæret som følger:

try {
    loginSocket = new Socket(_loginHost, _loginPort);
    output = new PrintWriter(new OutputStreamWriter(loginSocket.getOutputStream()));
    input = new BufferedReader(new InputStreamReader(loginSocket.getInputStream()));
} catch (UnknownHostException e) {
    System.err.println("Don't know about host: " + _loginHost); //$NON-NLS-1$
} catch (IOException e) {
    System.err.println("Couldn't get I/O for the connection to: " + _loginHost); //$NON-NLS-1$
}
Avatar billede dittmer Nybegynder
22. juni 2003 - 15:17 #15
arne_v: Der går ikke ret lang tid mellem læsning af prompt og afsendelse af brugernavn (< 0.5 sek ville jeg godt vædde om), og "i hånden" kan der gå meget længere tid. Jeg kan bare ikke helt forstå hvorfor jeg ikke kan læse på samme måde én gang til - det skulle vel være i orden?

Det virker som om den anden løkke terminerer med det samme (hvilket godt kan passe med din teori), men som sagt forstår jeg det ikke. Hvis den pågældende socket var blevet termineret, skulle jeg jo få en exception, når jeg forsøger at bruge den...
Avatar billede arne_v Ekspert
22. juni 2003 - 15:20 #16
Du kan evt. også prøve med output.flush() og se om det hænger
i en buffer.
Avatar billede dittmer Nybegynder
22. juni 2003 - 16:38 #17
Jeg har sat tider på outputtet:

16:29:48.557 : Started networking
16:29:48.737 : Created sockets
[...stuff...] Authentication Server
Login:
16:29:48.743 : Printed first prompt
16:29:48.744 : Wrote username
16:29:48.745 : Cleared input buffer

16:29:48.746 : Printed second prompt
16:29:48.747 : Finished

Som I kan se, er der ikke noget i inputbufferen anden gang, jeg læser fra den. Den skal da ikke resettes eller så'n, vel?


Sovsen (relevante dele af den) er her:

Socket loginSocket = null; 
PrintWriter output = null;
BufferedReader input = null;

try {
    timedProgress("Started networking");
               
    loginSocket = new Socket(_loginHost, _loginPort);
    output = new PrintWriter(new OutputStreamWriter(loginSocket.getOutputStream()));
    input = new BufferedReader(new InputStreamReader(loginSocket.getInputStream()));
} catch (UnknownHostException e) {
    System.err.println("Don't know about host: " + _loginHost); //$NON-NLS-1$
} catch (IOException e) {
    System.err.println("Couldn't get I/O for the connection to: " + _loginHost); //$NON-NLS-1$
}

timedProgress("Created sockets");
                                                 
StringBuffer received = new StringBuffer();
try {
    char c;
    while (input.ready() && (-1 != (c = (char) input.read()))) {
        received.append(c);
    }
    System.out.println(received);

    timedProgress("Printed first prompt");

    output.write(_username + "\n");

    timedProgress("Wrote username");
                                           
    received.delete(0, received.length()-1);

    timedProgress("Cleared input buffer");
                                           
    while (input.ready() && (-1 != (c = (char) input.read()))) {
        received.append(c);
    }
    System.out.println(received);
               
    timedProgress("Printed second prompt");

} catch (IOException ioe) {
    System.err.println("Couldn't get I/O for the connection to: " + _loginHost); //$NON-NLS-1$
}
           
timedProgress("Finished");
Avatar billede arne_v Ekspert
22. juni 2003 - 16:41 #18
Prøv og sæt en output.flush() ind efter at have sendt brugernavn.
Avatar billede dittmer Nybegynder
22. juni 2003 - 16:47 #19
output.flush() har ingen effekt...
Avatar billede arne_v Ekspert
22. juni 2003 - 16:49 #20
Har du prøvet med:

output.write(_username + "\r");

?

[og jeg tro stadigvæk at flush er en god ting - også selvom den ikke løste problemet]
Avatar billede dittmer Nybegynder
22. juni 2003 - 16:51 #21
Jeg kan se, at kaldet til input.ready() returnerer false. Hvorfor gør det nu det? Er der (nu igen) noget, jeg ikke har fanget??
Avatar billede dittmer Nybegynder
22. juni 2003 - 17:01 #22
Det giver ingen forskel at benytte

    output.write(_username + "\r");

- og jeg giver dig ret i det med .flush()...
Avatar billede arne_v Ekspert
22. juni 2003 - 22:37 #23
Prøv evt. at ligge en lille wait ind mellem write af username og
forsøg på at læse password prompt.

Thread.sleep(1000) f.eks..
Avatar billede dittmer Nybegynder
22. juni 2003 - 23:20 #24
Damn, Arne. Der var den...
Jeg havde forsøgt at lave en wait() på min inputsocket, men det gik ikke rigtigt. Den blev i hvertfald ikke notified senere...

Tak for'et...

Mit næste problem er selvfølgelig at finde ud af hvor lille en sleep() jeg kan bruge, og samtidig være 99.9% sikker på, at den faktisk er klar. Men det kan jeg jo klare ved at sleep()'e nogle millisekunder, checke om input er klar osv.

Smider du ikke lige et svar?

Mvh
Søren
Avatar billede dittmer Nybegynder
23. juni 2003 - 00:10 #25
Minimum sleep() ligger omkring 26 ms, men der er set sleep() på 50 ms, der fejler som ovenstående...
Jeg hader sådan nogle tilfældige begrænsninger...
Avatar billede swaq Nybegynder
23. juni 2003 - 02:38 #26
Jeg er lige kommet tilbage fra en hinsidig verden (læs: Roskilde Festival), hæ hæ... Kan se Arne_v (endnu engang) har udført et glimragende og fremstående stykke arbejde, hvorfor jeg skal fraholde mig fra at uddybe yderligere. Bortset fra det er du meget velkommen til at anvende min kode (hvis du kan få den til at virke :O) Arne_v har forresten hjulpet med den kode også :-)


/SWAQ
Avatar billede arne_v Ekspert
23. juni 2003 - 07:24 #27
Brug 100 ms eller sådan noget.

Login er jo beregnet til mennesker. Man skal være hurtig på
tasterne for at indtaste username ved prompten på 100 ms.

:-)
Avatar billede arne_v Ekspert
23. juni 2003 - 07:25 #28
svar
Avatar billede dittmer Nybegynder
23. juni 2003 - 08:19 #29
Arne: Det har været 100ms siden lidt før 00:10:39... Det er klart, at login ikke har haft mig i tankerne under design ;o), men i øvrigt mener jeg, at Karthago bør ødelægges, at tofu, oliven og kikærter er stærkt overvurderet som menneskeføde, samt at applikationsintegration via telnet og login-interface er noget lort... Så det...

Tak for hjælpen - jeg uddeler en skæv fordeling...
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester