String <=> cli::array<unsigned char,1>^ Umwandlung

Hi


Ich hab mich mal an ein HTTP-Client in C++(Visual C++ 2005 Express) drangegeben.
Meine Funktion bis jetzt:
Code:
				TcpClient^ client = gcnew TcpClient("127.0.0.1", 80);
				NetworkStream^ stream = client->GetStream();
				
				cli::array<unsigned char,1>^ data;
				cli::array<unsigned char,1>^ dat;
				dat = gcnew array<Byte>(4098);
				data = System::Text::Encoding::ASCII->GetBytes(input->Text+"\r\n\r\n");
				data[0] = (unsigned char) "T";
				stream->Write( data, 0, data->Length);
				
				if(stream->CanRead){
					stream->Read(dat,0,dat->Length);
					//System::Text::Encoding::UTF8
					ausgabe->Text = System::Text::Encoding::ASCII->GetString(dat);
				}
				client->Close();

So das Problem:

Wenn ich jetzt als Text "GET / HTTP\1.1" eingebe steht in der access.log vom Apache:
"|ET / HTTP\x01.1"

Soweit ist das ja noch nicht schlimm, da der Befehl trotzdem ausgeführt wird und ich eine Korrekte antwort bekomme

"HTTP/1.1 302 Found
Date: Thu, 07 Feb 2008 16:57:53 GMT
Server: Apache/2.2.6 (Win32) DAV/2 mod_ssl/2.2.6 OpenSSL/0.9.8g mod_autoindex_color PHP/5.2.5
X-Powered-By: PHP/5.2.5
Location: hps/main/
Content-Length: 0
Connection: close
Content-Type: text/html"


Sobald ich aber als Text "GET /benny/ HTTP\1.1" eingebe, kommt Function not implemented
HTTP/1.1 501 Method Not Implemented

Date: Thu, 07 Feb 2008 16:58:31 GMT
Server: Apache/2.2.6 (Win32) DAV/2 mod_ssl/2.2.6 OpenSSL/0.9.8g mod_autoindex_color PHP/5.2.5
Vary: accept-language,accept-charset
Accept-Ranges: bytes
Connection: close
Content-Type: text/html; charset=iso-8859-1
Content-Language: en
Expires: Thu, 07 Feb 2008 16:58:31 GMT

Habe ich die umwandlung von System::String^ nach cli::array<unsigned char,1>^
falsch?

Thx im voraus

p.s GET /benny HTTP\1.1 geht(also /benny, nicht /benny/)
 
Gehe schrittweise vor! Prüfe erstmal, wie die Daten nach Deiner Manipulation vor dem Absenden an den Server aussehen!

Warum tauschst Du den ersten Buchstaben der Anfrage gegen ein "T" aus?
Bist Du Dir sicher, daß bei Dir ein "char" einem "Byte" entspricht?
Ich möchte wetten, daß "chars" bei Dir als UTF16 behandelt werden...
Dann dürften durch Zeile 8 ein "T" und ein Nullbyte geschrieben werden.

Allerdings wundere ich mich hochgradig über die daraus resultierende Ausgabe auf Seite des Servers...

Also: EIGENTLICH müßte der als Anfrage bekommen:
"T"<Null>"GET..."
und DAS müßte von ihm eigentlich rundweg abgelehnt werden.

Meine Empfehlung:
1. Laß die Zeile 8 weg!
2. Kontrolliere die "data" vor dem Absenden!
 
Huch wo kommt denn das durch T ersetzen her o_O

Du hast recht, nach dem löschen vom dem T-replace funktioniert es

Was meinst du mit UTF16, soll ich UTF16 als Encodierung benutzen nicht ASCII?

In der log steht jetzt:
127.0.0.1 - - [07/Feb/2008:20:34:19 +0100] "GET /benny HTTP\x01.1" 301 369
aber warum \x01.1 ?

Stimmt da immer noch was nicht?


Thx schonmal 4 hilfe
 
Huch, ja: Entweder das "ASCII->GetBytes" oder das "input->Text" betrachtet einen Backslash als Escape-Zeichen oder so ähnlich und tauscht das Ding gegen "\x0" aus. Das mußt Du entweder abschalten oder rückgängig machen! Wie man das abschalten kann, ist mir aber nicht bekannt (ich habe kein VC5 und benutze daher auch kaum die MS-Bibliotheken).

Und: Wie Du das sonst machst, ist das ganz OK. Soweit ich weiß, ist sowohl ASCII als auch UTF8 im Netz üblich. Meine Apache-Server konfiguriere ich immer so, daß sie beides verstehen. Viele Admins machen das so, weil's gar nicht anders geht. Also laß den Rest, wie er ist! (Das mit dem UTF16 hatte ich nur im Zusammenhang mit dem "T" von Zeile 8 eingeworfen, um mir die Reaktion des Webservers zu erklären...)
 
ok ich werds morgen mal testen



Thx

Edit: Funktioniert soweit gut :)
Nur hab ich jetzt das Problem das wenn ich eine Seite anfordere, der Einlesungsprozess nach einer Zeit unterbrochen wird.

z.b.

...<div class="asd">asd</div></div><div class="asd"><a href="http://[ENDE]

der Code:

Code:
cli::array<unsigned char,1>^ dat;
dat = gcnew array<Byte>(99999);
[...]
while(stream->CanRead && stream->DataAvailable==false){
stream->Read(dat,0,dat->Length);
ausgabe->Text += System::Text::Encoding::ASCII->GetString(dat)+"\r\n---\r\n";
}

Dafür eine Idee?

Edit2: es sind auch keine --- vorhanden.

Kann es an einem \0 liegen? und wie könnte ich das abfangen?
 
Wenn Du es so machst:
Code:
while(...stream->DataAvailable==false)
wirst Du nur ein einziges Mal - nachdem die ersten Daten einen Weg in den Netzwerk-Puffer gefunden haben - Daten bekommen. Ganz genau wie beschrieben.

Du solltest Daten abrufen, bis der stream eine Art End-Of-File liefert. Wie das bei der NET-Runtime-Umgebung aussieht, weiß ich allerdings nicht.

Wie ich das aus http://msdn2.microsoft.com/en-us/library/system.net.sockets.networkstream.read.aspx herauslese, wartet NetworkStream::Read solange, bis IRGENDWELCHE Daten eingetroffen sind ODER die Gegenstelle die Verbindung kappt (was AUCH geschieht, nachdem von einem HTTP-Server die Antwort komplett eingetroffen ist). Du kannst Dir also den Test vornweg ersparen und einfach SOLANGE lesen, wie IRGENDWAS zurückkommt.

Das brauchst Du jetzt bloß noch als "while" zu schreiben...
 
Original von Harry Boeck
Wenn Du es so machst:
Code:
while(...stream->DataAvailable==false)
wirst Du nur ein einziges Mal - nachdem die ersten Daten einen Weg in den Netzwerk-Puffer gefunden haben - Daten bekommen. Ganz genau wie beschrieben.

Du solltest Daten abrufen, bis der stream eine Art End-Of-File liefert. Wie das bei der NET-Runtime-Umgebung aussieht, weiß ich allerdings nicht.

Wie ich das aus http://msdn2.microsoft.com/en-us/library/system.net.sockets.networkstream.read.aspx herauslese, wartet NetworkStream::Read solange, bis IRGENDWELCHE Daten eingetroffen sind ODER die Gegenstelle die Verbindung kappt (was AUCH geschieht, nachdem von einem HTTP-Server die Antwort komplett eingetroffen ist). Du kannst Dir also den Test vornweg ersparen und einfach SOLANGE lesen, wie IRGENDWAS zurückkommt.

Das brauchst Du jetzt bloß noch als "while" zu schreiben...
Jo thx ich glaub ich habs jetzt:

Code:
stream->ReadTimeout = 100;
int c = 1;
while(stream->CanRead&&c!=0){
c = stream->Read(dat,0,dat->Length);		
ausgabe->Text += System::Text::Encoding::ASCII->GetString(dat)+"\r\n---\r\n";
debug->Text += "[INFO]"+c+" Bytes read\r\n";
}


THX?
 
Zurück
Oben