| |

VB.NET - Ein- und UmsteigerRe: Telnet - von Windows auf Unix zugreifen - Invoke oder Thread | |  | Autor: Preisser | Datum: 10.04.12 15:55 |
| Hallo,
jasmina schrieb:
Zitat: |  | Hallo,
danke für Deinen Hinweis auf den Zeilenumbruch. Anschließend funktioniert zwar das Senden aber
wohin? Entweder in der Routine 'Nachricht_lesen' bei der vorletzten Zeile bleibt das Programm hängen und/oder die Antwort besteht aus: '??!??&' |  |
Also das echte Telnet-Protokoll ist ja kein rein zeichenbasiertes Protokoll, sondern es gibt bestimmte "Commands". RFC 854 (Seite 14):
Zitat: |  | All TELNET commands consist of at least a two byte sequence: the
"Interpret as Command" (IAC) escape character followed by the code
for the command. The commands dealing with option negotiation are
three byte sequences, the third byte being the code for the option
referenced. |  |
Darunter sind dann einige Bytewerte aufgelistet, die für unterschiedliche Commands stehen. Wenn ich mich beispielsweise zu einem Windows Server per Telnet verbinde, erhalte ich am Anfang die Bytesequenzen (Hex)
FF FD 25 FF FB 01 ... Das Byte FF (dez. 255) steht dabei für "IAC" (Interpret As Command), also eine Anweisung, den darauffolgenden Bytecode (FD) als Kommando zu interpretieren. Bei manchen Commands folgt dann ein Option Code als weiteres Byte. Ich hab jetzt aber nicht näher geschaut, was die einzelnen Commands dann bedeuten.
Dass bei dir Fragezeichen ankommen, liegt daran, dass du ja ASCII zum Konvertieren der Bytes in Text verwendest; dieses aber nur für 7 Bit festgelegt ist (also Bytewerte 0-127). Alle Bytes darüber werden als "?" dekodiert (vermutlich ebenfalls ein IAC + Command + Option Code usw.). Du müsstest also mal die Bytes direkt auslesen (ohne sie in Text zu konvertieren) und eben schauen, was der Server für Commands sendet.
Zitat: |  | Der Port ist zum Senden die 23 -
kann es jedoch sein, dass beim Antworten ein anderer Port verwendet wird? - |  |
Der Port 23 ist der Port des Servers, an dem dieser auf eingehende TCP-Verbindungen lauscht. Zum Herstellen der Verbindung wird zwar auch beim Client ein freier TCP-Port verwendet, diesen muss man für die normale Kommunikation aber nicht wissen, denn eine TCP-Verbindung ist immer bidirektional, also besteht aus einem Sende- und Empfangskanal. Wenn man eine TCP-Verbindung herstellt, kann man damit auch automatisch Daten empfangen.
Zitat: |  | Und wohin oder wie sollte ich BeginInvoke() setzen?
Programm sowie den Sende- und Empfangsteil in ein eigenes Thread verlagert. |  |
Du könntest das BeginInvoke() z.B. dann aufrufen, wenn der Lesethread wieder eine Nachricht gelesen hat (was man als Nachricht bezeichnet, hängt dann vom Protokoll ab). Z.B. gehären ja beim Telnet-Protokoll manchmal mehrere Bytes zu einem Command, also kann es sinvoll sein, erst mal das vollständige Command zu lesen, bevor man es an den GUI-Thread weitergibt.
Soweit ich aus deinem Code sehe, erstellst du aber anscheinend 2 Threads, die jeweils SendNachricht aufrufen, und zusätzlich rufst du es nochmal vom GUI-Thread aus auf - in einen Stream sollte aber jeweils immer nur ein Thread gleichzeitig schreiben. Ich verstehe auch nicht ganz, warum du eine globale Variable "NByte" hast, die von Nachricht_senden() gelesen und in den Stream geschrieben wird, und dann von Nachricht_lesen() vom Stream in dieses Byte-Array gelesen wird (und dann nochmal in einen anderen Puffer, wobei die Zeile
responseData = System.Text.Encoding.ASCII.GetString(Buffer, 0, _
Buffer.Length) eigentlich auch nicht ganz korrekt ist, da die Stream.Read(Byte(), Int32, Int32)-Methode auch weniger Bytes lesen kann, als im Parameter angegeben wurden).
Mit den Threads meinte ich, dass man z.B. einen Thread erstellt, der solange aus dem Stream liest, bis nichts mehr da ist (d.h. die Read()-Methode gibt 0 zurück), oder eine Exception auftritt (z.B. IOException bei einem Lesefehler oder ThreadInterruptedException, wenn der Thread interrupted wurde). Wenn er dann ein Paket empfangen hat, ruft er z.B. BeginInvoke() bei einer Form auf und übergibt das Paket. Fürs Senden könnte man einen Thread erstellen, der z.B. aus einer BlockingCollection(T) Sendeaufträge holt, die die GUI dort einfügt.
Wie gesagt, kann es aber beim Telnet-Protokoll Sinn machen, nicht direkt jedes empfangene Byte-Paket an die GUI zu leiten, sondern z.B. bei Commands diese komplett lesen, bevor man sie an die GUI weitergibt. Allerdings kenn ich mich mit dem Telnet-Protokoll leider nicht aus, um zu sagen, wie genau es funktioniert.
Beitrag wurde zuletzt am 10.04.12 um 16:07:15 editiert. |  |
 | Sie sind nicht angemeldet! Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.
Einloggen | Neu registrieren |
  |
|
sevISDN 1.0 
Überwachung aller eingehender Anrufe!
Die DLL erkennt alle über die CAPI-Schnittstelle eingehenden Anrufe und teilt Ihnen sogar mit, aus welchem Ortsbereich der Anruf stammt. Weitere Highlights: Online-Rufident, Erkennung der Anrufbehandlung u.v.m. Weitere InfosTipp des Monats Neu! sevDTA 3.0 Pro 
SEPA mit Kontonummernprüfung
Erstellen von SEPA-Dateien mit integriertem BIC-Verzeichnis und Konto- nummern-Prüfverfahren, so dass ungültige Bankdaten bereits im Vorfeld ermittelt werden können. Weitere Infos
|