Als halbwegs leidlicher C-, aber ziemlich ahnungsloser C++ Programmierer
dingse ich gerade an einem einfachen Telnet-Client herum.
Nach dem Connect schickt der Server sofort eine Begrüßung zurück -
leider ist aber davor und danach ne Menge Müll dabei. Wo liegt der/die
Fehler?
mal hier schauen:
Das Kernprotokoll wird in den IETF-Dokumenten RFC 854 und RFC 855 (STD
8) beschrieben. STD 8 beschreibt einige grundsätzliche Arbeitsweisen des
Protokolls und Erweiterungsmöglichkeiten.
MfG Klaus
>Das Kernprotokoll wird in den IETF-Dokumenten RFC 854 und RFC 855 (STD>8) beschrieben.
Hmm. Ich bin nicht sicher ob das mein Problem löst. Funktionieren tut's
ja. Ich hab eben mal von message[200] alle chars mit '\0' formatiert,
danach ging gar nix mehr. Sieht so aus als ob sich C und VC++ stark
unterscheiden und Speicher unterschiedlich gehandhabt und verwaltet
wird.
Joachim ... schrieb:> Funktionieren tut's ja.
Das sehe ich ganz anders. Das du ab und an mal lesbare ASCII Zeichen
findest, heißt nicht, das auch nur irgendein Stück des Telnet Protokols
funktioniert. Lesen bildet !
MfG Klaus
Von der fehlenden Telnet-Implementierung mal abgesehen:
der Rückgabewert von recv ist die Anzahl der gelesenen Zeichen. Dem
String-Construktor musst du die mitgeben.
also sowas wie
std::string received_text(message,answer);
...
std::cout << received_text;
>Von der fehlenden Telnet-Implementierung mal abgesehen:
Was bedeutet das? Ich hab noch nen Teil in ner h.Datei stehen:
#pragma once
#pragma comment(lib, "Ws2_32.lib")
#include <sdkddkver.h>
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <string>
Oder meinst du etwas anderes?
Joachim ... schrieb:> Oder meinst du etwas anderes?
Telnet ist mehr als "TCP auf den Bildschirm bringen", da ist ein
Protokoll mit Handshake zwischen Client&Server mit dabei, dieses
implementierst du nicht.
Joachim ... schrieb:> Ich hab eben mal von message[200] alle chars mit '\0' formatiert,> danach ging gar nix mehr. Sieht so aus als ob sich C und VC++ stark> unterscheiden und Speicher unterschiedlich gehandhabt und verwaltet> wird.
Nein, da gibt es keinen Unterschied, sofern Du mit "VC++" nicht die auf
dem .Net-Geraffel aufsetzende Microsoft-Perversion namens "C++/CLI" bzw.
"Managed C++" meinst.
Wie hast Du "alle chars mit '\0' formatiert"?
Hast Du Dir mal den Rückgabewert von recv näher angesehen? Was mag der
für eine Bedeutung haben?
Wie hast Du "alle chars mit '\0' formatiert"?
char message[200] funktioniert jetzt vernünftig.
Aber vermute ich werde doch erst nen paar Grundlagen in Erfahrung
bringen müssen.
Hab eben noch mal nen send/recv Austausch mit Steuerzeichen für den
Multimeter an den Server probiert, da gabs dann ne Meldung daß das Array
message[] korrupt wäre...
Hm.
Schönen dank erstmal.
1. Vor strmessage = message sollte message mit '\0' enden. Z.b.
message[answer] = 0;
2. Nach dem Verbindungsaufbau werden bei Telnet zwischen Client und
Server diverse Optionen ausgehandelt. Dazu senden beide Seiten WILL,
WONT, DO, DONT fuer die verschiedenen Optionen bis zur Einigung. Lies
das noch mal in http://www.faqs.org/rfcs/rfc854.html und
http://www.faqs.org/rfcs/rfc855.html nach.
LG, Sebastian
ssh kann auch wunderbar remote commandos ausführen.
z.b. "ssh kiste ls" führt ein ls auf "kiste" aus.
Dazu benutzt man Keys ohne passphrase und begrenzt die commandos in der
authorizedkeys.
Fertig ist der Lack!
>Dazu benutzt man Keys ohne passphrase und begrenzt die commandos in der>authorizedkeys.
Nicht zielführend.
>Nach dem Verbindungsaufbau werden bei Telnet zwischen Client und>Server diverse Optionen ausgehandelt.
Aaaaaha! Daher auch die Sonderzeichen vor der eigentlichen textuellen
Begrüßung. Danke!
Dann müßte ich die wohl bloß ausblenden?
Wie auch immer. Ich hab den Code (stammt aus nem Tutorial) jetzt am
laufen, allerdings werden nach ein paar Minuten keine Daten mehr an den
Server im Multimeter übertragen... als ob es zu einem Pufferüberlauf
kommt. Muß ich irgendwo zwischendurch Daten abholen oder so ne Art
Quittierung senden? Mülle ich den Socket zu? Wie gesagt, ich hab mitm
schreiben von Netzwerkanwendungen keine und mit VC++ nur sehr wenig
Erfahrung.
Na, was geht da wohl schief?
Besorg Dir ein C-Buch. Empfehlung: Brian Kernighan & Dennis Ritchie,
"Programmieren in C", Zweite Ausgabe, Hanser-Verlag.
Da das, was Du da machst, sowieso kein C++ ist (außer dem Nutzen von
cout), passt das; und das, was Du da falsch machst, ist auch in C++
falsch.
Rufus Τ. Firefly schrieb:> was Du da falsch machst, ist auch in C++> falsch.
Nicht nur in C++ ;-)
Die ganzen Probleme entstehen hier meiner Meinung nach einfach weil
unstrukturiert vorgegangen wird. Und an den symptomen herumgedocktert
wird.
Joachim ... schrieb:> Aaaaaha! Daher auch die Sonderzeichen vor der eigentlichen textuellen> Begrüßung. Danke!> Dann müßte ich die wohl bloß ausblenden?
Schau doch einfach mal in das Dokument, lese (und beantworte) die
Anfragen und gib nicht alles stur aus. Was ist überhaupt dein Ziel?
Telnet-Clients gibt es ja wohl wie Sand am Meer (auch skripting fähige).
>Na, was geht da wohl schief?
;-)
>Das sehe ich ganz anders. Das du ab und an mal lesbare ASCII Zeichen>findest, heißt nicht, das auch nur irgendein Stück des Telnet Protokols>funktioniert. Lesen bildet !
Ok, ich seh's ein. Mein Client scheint da ein paar Bedingungen zu
übergehen. Auch ist das Fehlerverhalten nicht immer gleich. Werd' mich
wohl tiefer einlesen müssen bevor ich den nächsten Versuch starte...
Warum nimmst du denn den telnet Port?
Das Gerät (Agilent 34410A aus deinem Bild) hat auch ganz normale Sockets
ohne großes Protokoll.
Nachdem was ich in 10 Minuten im Netz gelesen habe, sind das die Ports
5025 oder 5042.
Das kann man aber auch sicher einstellen.
Zum Probieren kannst du auch Putty nehmen. Das kennt Telnet und auch
einen Raw-Mode.
Oder mit netcat von der Kommandozeile zum ausprobieren.
Mmmhhh ja, das mit 5025 hab ich probiert, aber da stellt sich der Socket
im Moment noch tot. Mit Putty geht's.
>hat auch ganz normale Sockets>ohne großes Protokoll.
Sagen wir mal so: mit dem obigen paar Zeilen funktioniert's. Ich hab
auch nen Source von Agilent in dem der Datenaustausch rein funktional
gesehen nach dem gleichen Arme-Leute-Schema abläuft. Also nix groß
Protokoll, nix DO, DONT, WILL und WONT... und so - allerdings mit Port
5025 statt 5024. Es funktioniert unter Putty sogar(?) der Raw-Mode.
Ich habe jetzt auch meinen Fehler gefunden. Bei jeder Anweisung sendet
der Server die ASCII-Kette "34410A>" zurück. Das geht natürlich nur so
lange gut bis der Empfangspuffer voll ist... Ein Dummy-read hat das
Problem gelöst.
Joachim ... schrieb:> Bei jeder Anweisung sendet> der Server die ASCII-Kette "34410A>" zurück
Kommt das auch mit PUTTY ?
Im Raw-Modus (Port 5025) und/oder im Telnet-Modus (Port 5024)?
>Kommt das auch mit PUTTY ?>Im Raw-Modus (Port 5025) und/oder im Telnet-Modus (Port 5024)?
Ja, sowohl bei Putty und auf 5024 unabhängig vom Telnet-Client. Bei
"Raw" weiß ich nimmer genau, denke aber schon. Auf 5025 kommt nur nen LF
zurück.
Hab jetzt ne Verbindung auf 5024 seit fast drei Std am Laufen und
schicke ununterbrochen alle paar zehntel Sekunden ne Anfrage. Funzt
einwandfrei.
Falls es dich interessieren sollte was Agilent dazu vorschlägt:
http://www.staff.uni-bayreuth.de/~btp918/cmt2007/geraete/agilent_34410A_dmm/manual/SCPI_Sockets.pdf
Wie gesagt, ist inhaltlich das Gleiche wie das was ich in nem Tut
gefunden hab.
Dann wird das "34410A>" das Prompt sein.
Zur Steuerung von einem Programm aus ist der reine Socket (5025)
wesentlich besser geeignet.
Vor allem weil das Übertragungsende durch ein \r\n angezeigt wird.
Da brauchst du auch nicht mehr die ganzen Sleep in deinem Code.