Telnet Client // Probleme mit dem auslesen des Puffers



  • // telnet.cpp: Hauptprojektdatei.
    
    #include "stdafx.h"
    
    using namespace System;
    using namespace System::Collections::Generic;
    //using namespace System.Linq;
    using namespace System::Text;
    using namespace System::Net::Sockets;   // TCP-streaming
    using namespace System::Threading;     // the sleeping part...
    
    int main(array<System::String ^> ^args)
    {
    	/* *******************   Commands  ************************ */
    
    	// Password
    	String ^password = "XXXXXXXX";
    
    	// Command
    	String ^User = "root"; // User
    
    	/* *******************   Server config  ******************* */
    
    	// Server Port
    	Int32 port = 23;
    
    	// Server Hostname
    	TcpClient ^client = gcnew TcpClient("192.168.1.38", port);
    
    	/* *******************   Conversion  ********************** */
    
    	// Convert password in ASCII and write it into a byte-array              
    	Encoding ^enc = Encoding::ASCII;
    	array <Byte> ^data = enc->GetBytes(password);
    
    	// Convert command in ASCII and write it into a byte-array                
    	array <Byte> ^data2 = enc->GetBytes(User);
    
    	/* *******************   Initialisation  ****************** */
    
    	// Client-Stream
    	NetworkStream ^stream = client->GetStream();
    
    	/* *******************   Send commands  ******************* */
    
    	// Send User
    	Console::WriteLine("Sende Benutzer\n");
    	stream->Write(data2, 0, data2->Length);
    	Console::WriteLine("Benutzer gesendet\n");
    
    	// Send password
    	Console::WriteLine("Sende Passwort\n");
    	stream->Write(data, 0, data->Length);
    	Console::WriteLine("Passwort gesendet\n");
    
    	// Just wait a sec...
    	Console::WriteLine("Warte 1 Sekunde\n");
    	Thread::Sleep(1000);
    	Console::WriteLine("1 Sekunde gewartet\n");
    
    	/* *******************   Recieve  ************************* */
    
    	// Strings for ASCII stream
    	String^ responseData  = String::Empty;
    	String^ responseData2 = String::Empty;
    
    	// Read first stream
    	Int32 bytes  = stream->Read(data, 0, data->Length);
    	responseData = enc->GetString(data, 0, bytes);
    
    	// First stream output
    	Console::WriteLine(responseData);
    
    	// Read second steam
    //	Int32 bytes2 = stream->Read(data2, 0, data2->Length);
    //	responseData2 = enc->GetString(data2, 0, bytes);
    
    	// Second stream output
    	Console::WriteLine(responseData2);
    
    	/* *******************   Close  **************************** */
    
    	// Close stream/TCP-client
    	stream->Close();
    	client->Close();
    
    	/* *******************   Error handling  ******************** */
    
    	// Don`t close the console...
    	Console::WriteLine("\n Press Enter...");
    	Console::Read();
    	return 0;
    }
    

    Ich habe hier ein von C# in CLI konvertierten Telnet Clienten (von einem Fern Lehrer umgeschrieben aber nicht getestet und auch ein rein privates Projekt und keine Hausaufgabe 😉 ). Dieser soll in meinem Fall mit einem Linux Receiver kommunizieren.

    Leider scheint allerdings der Zeichensatz nicht zu stimmen, oder es stimmt sonst etwas nicht.... Leider kann ich das Problem nicht weiter eingrenzen.

    Als Ausgabe erhalte ich:

    "?? 🙂 ??" -->Ja der Smily ist Absicht.

    http://www.abload.de/img/unbenanntbxfpp.jpg

    Ich hoffe es kann mir jemand helfen.
    Natürlich ist auch die Übertragung eines Commands
    mit den falschen Zeichen nicht möglich.

    Ich habe auch schon versucht den Encoder umzustellen, allerdings erhalte ich dann auch nur "?" oder andere Sonderzeichen in der Ausgabe.

    Vielleicht kann mir ja jemand helfen..... Danke!

    Pascal



  • So, für alle die auch mal das Problem haben:

    Telnet sendet erstamal Commandos und wenn ich die in ASCII wandle kommen eben die "?????" dabei raus.
    Liest man den Puffer nochmal aus bekommt man die Daten!

    // Telnet_Bytes.cpp: Hauptprojektdatei.
    
    #include "stdafx.h"
    
    using namespace System;
    using namespace System::Collections::Generic;
    using namespace System::Text;
    using namespace System::Net::Sockets;   // TCP-streaming
    using namespace System::Threading;      // the sleeping part...
    
    ref class cClient{
    
    private:
    	//Festlegen der Commandos
    
    	const	static Byte WILL	= 251;
    	const 	static Byte WONT	= 252;
    	const 	static Byte DO		= 253;
    	const 	static Byte DONT	= 254;
    	const 	static Byte IAC		= 255;
    	const 	static Byte SGA		= 3;
    
    	const	static Byte TimeOut = 100;
    
    public:
    	NetworkStream^ ClientStream;
    	TcpClient ^Client;
    
    	TcpClient	^cClient::Init(String^ server, Int32 Port){
    
    		TcpClient ^Client = gcnew TcpClient(server, Port);
    
    		return Client;
    
    	}
    
    	String		^cClient::Lesen		(TcpClient ^Client, NetworkStream ^stream){
    
    		Encoding^ ascii = Encoding::ASCII;
    		array <Byte> ^arrInput = gcnew array <Byte> (256);
    
    		Int32 inputverb, inputoption, input, Durchlaeufe = 0;
    		StringBuilder ^sb = gcnew StringBuilder;
    		String ^responseData;
    
    		Thread::Sleep(TimeOut);
    
    		while(Client->Available > 0 || Durchlaeufe < 5){			//Durchläufe damit alles aus dem Cache gelesen wird
    
    			input = stream->ReadByte();
    
    			switch (input)
    			{
    			case IAC:
    				Thread::Sleep(TimeOut);
    
    				inputverb = stream->ReadByte();
    
    				switch (inputverb)
    				{
    				case IAC: 
    					break;
    				case DO: 
    				case DONT:
    				case WILL:
    				case WONT:
    					//Thread::Sleep(TimeOut);
    
    					inputoption = stream->ReadByte();
    
    					//	stream->WriteByte(IAC);
    					//	stream->WriteByte(inputverb == (DO ? WONT : DONT)); 
    					//	stream->WriteByte(inputoption);
    					break;
    
    				default:
    					break;
    
    				}
    				break;
    			default:
    				arrInput[0] = 0;
    				arrInput[0] = input;
    				responseData = ascii->GetString(arrInput,0,1);
    
    				sb->Append( responseData );
    				break;
    			}
    			Durchlaeufe++;
    		}
    
    		Durchlaeufe = 0;
    		return sb->ToString();
    	}
    
    	Void		 cClient::Schreiben	(TcpClient ^Client, NetworkStream ^stream, String ^msg){
    
    		msg = msg + "\r";		//\n für "Enter" übergabe
    		Encoding^ ascii = Encoding::ASCII;
    		array<Byte>^data =ascii->GetBytes( msg->Replace("\0xFF","\0xFF\0xFF") );
    
    		for(Int32 i = 0; i<data->Length;i++)
    			stream->WriteByte(data[i]);
    	}
    
    	Void		 cClient::CloseClient	(TcpClient ^Client){
    
    		Client->Close();
    
    	}
    };
    
    int main(array<System::String ^> ^args)
    {
    
    	//Neue Telnet Client Klasse
    	cClient ^NewClient = gcnew cClient;
    
    	//Neue TCPClient Verbindung
    	TcpClient ^HauptClient = NewClient->Init("vuuno", 23);
    
    	//Neuer Netzwerkstream
    	NetworkStream^ ClientStream = HauptClient->GetStream();
    
    	String ^MessageRecived, ^eingabe =" ";
    	Boolean open = true;
    
    	while (open)
    	{
    
    		MessageRecived = NewClient->Lesen(HauptClient, ClientStream);
    
    		MessageRecived = MessageRecived->TrimStart(eingabe->ToCharArray());
    		Console::Write(MessageRecived);
    
    		eingabe = Console::ReadLine();
    
    			if (eingabe == "exit"){
    				open = false;
    				NewClient->CloseClient(HauptClient);
    			}else
    				NewClient->Schreiben(HauptClient, ClientStream, eingabe);
    	}
    
    }
    

    Vielleicht kann ja mal jemand von den Erfahrenen drüber schauen und
    mir vielleicht sagen wo das Problem mit den Commando Antworten herkommt
    und warum es mit der Aktualisierung der Anzeige manchmal hapert?


Anmelden zum Antworten