Pages: [1]   Go Down
Author Topic: Frage zum Unterschied dieser beiden Codeschippsel...  (Read 896 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Full Member
***
Karma: 3
Posts: 112
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,
ich bin neu in der Arduino-Welt und hätte eine Verständnisfrage zu folgenden Codeschnippseln:

Code:

         //diese Variante funktioniert nicht im IE, dafür aber in Firefox, Chrome, Safari...
          client.println("HTTP/1.1 401 Authorization Required"); 
          client.println("Content-Type: text/html"); 
          client.println("WWW-Authenticate: Basic realm=\"Test\"");
          client.println();
          client.println("<HTML><HEAD><TITLE>Error</TITLE></HEAD><BODY><H1>401 Unauthorized.</H1></BODY></HTML>");


          //diese Variante funktioniert mit allen Browsern...
          //client.write("HTTP/1.1 401 Authorization Required\r\nContent-Type: text/html\r\nWWW-Authenticate: Basic realm=\"Test\"\r\n\r\n");
          //client.write("<HTML><HEAD><TITLE>Error</TITLE></HEAD><BODY><H1>401 Unauthorized.</H1></BODY></HTML>\r\n\r\n");

Was ist der Unterschied zwischen den beiden Schreibweisen?



Ich hänge als Anhang mal den kompletten Sketch an.

Vielen Dank für Eure Hilfe.
MfG paulinchen

* passwort.ino (3.2 KB - downloaded 9 times.)
Logged

Offline Offline
Full Member
***
Karma: 5
Posts: 193
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Die bewirken das gleiche.
Beim zeiten werden Zeilenumbrüche durch \n erzeugt.
Beim ersten wird das ausführlich ausgeschrieben.

Addi
Logged

  / \    _|  _| o
 /--\ (_| (_| |

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Der Unterschied liegt darin, dass die write()-Methode den ihr übergebenen Byte-Array nach Möglichkeit in einem Paket ausgibt. Die println()-Methode ist aber so implementiert, dass für jedes Byte die write()-Methode einzeln aufgerufen wird. Somit wird pro TCP/IP-Paket nur ein Byte effektiver Daten übertragen. In Deinem Beispiel fast 200 Pakete übertragen werden. Was natürlich höchst ineffizient ist. Die print() bzw. println()-Methoden sind zwar sehr angenehm zu benutzen, aber nicht wirklich für schlaue Anwendungen zu empfehlen. Man kann jetzt vortrefflich darüber streiten, ob die Print-Klasse oder die write()-Methode der Ethernet-Klasse unschön implementiert ist.

Nach den gültigen Standards müsste ein Browser die Daten aus den verschiedenen Paketen problemlos zusammensetzen können, aber der IE hat die Bezeichnung Browser ja auch nicht wirklich verdient smiley
Logged

Offline Offline
Full Member
***
Karma: 3
Posts: 112
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo pylon,
vielen Dank für Deine Antwort.

Das bedeutet, daß man bei der Implementierung eines Webservers generell nur client.write() nutzen sollte, oder?

MfG paulinchen
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 143
Posts: 2996
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Was ist der Unterschied zwischen den beiden Schreibweisen?

Das "println" hängt nur ein Linefeed Steuerzeichen "\n" an den String dran.

Das ist zwar legal, um die Zeilen im HTTP-Header zu trennen und auch und die Zeilen in der HTTP-Message zu trennen, aber es ist gemäss HTTP-Standard nicht legal, um die Header-Response von Body der Message zu trennen.

Siehe HTTP-Normung beim W3C:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html

Header und Body werden mit zweimal hintereinander CRLF ("\r\n") voneinander getrennt, wenn es HTTP-standardkonform sein soll.

Deine erste Version sendet das Steuerzeichen CR ("\r") aber überhaupt nicht, weil println das nicht als Zeilenende-Zeichen mitsendet.

Der wesentliche Unterschied auf den es ankommt ist das "\r\n\r\n" am Ende der Zeile:
> ... WWW-Authenticate: Basic realm=\"Test\"\r\n\r\n");

Das ist der standardkonforme Trenner zwischen HTTP-Header und HTTP-Message.





Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So ganz generell würde ich dem nicht zustimmen, aber wenn Du Wert darauf legst, dass das sich nicht an Standards haltende Ding von Microsoft auch zugreifen können soll, wirst Du wahrscheinlich nicht darum herum kommen.

Die Print-Klasse hat aber durchaus auch ihre Vorzüge. z.B. kannst Du dort einfach das F()-Macro verwenden und sparst dadurch viel RAM ein. Das mit vernünftigem write()-Aufruf abzubilden macht Kompromisse nötig.

@jurs: println() hängt ein "\r\n" an das Argument an (und nicht nur ein "\n"), aber es ruft eben die write()-Methode byte-weise auf.
Logged

Offline Offline
Full Member
***
Karma: 3
Posts: 112
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ja, momentan nutze ich client.println(F("textstring"));

Aber mit Hilfe der Flash-library könnte ich ja Flash-strings definieren und diese dann mit client.write() nutzen...

Ich werde dann wohl mal mein Programm umstellen...

Vielen Dank an alle.
MfG paulinchen
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Aber mit Hilfe der Flash-library könnte ich ja Flash-strings definieren und diese dann mit client.write() nutzen...

Ich weiss nicht, welche Flash-Library Du meinst, aber so einfach dürfte das nicht werden. Wenn Du die Strings des F()-Macros meinst, die kannst Du nicht direkt per write() ausgeben.
Logged

Offline Offline
Full Member
***
Karma: 3
Posts: 112
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,
ich definiere halt die Flash-strings im PROGMEM:

     FLASH_STRING(FS_404_Header, "HTTP/1.1 404 Not Found\r\nContent-Type: text/html\r\n\r\n");

und im Programmablauf kopiere ich diese dann bei Bedarf ins RAM:

     FS_404_Header.copy(my_flash_buf);

und sende sie an den client:

     MyClient.write(my_flash_buf);

Funktioniert prima.
MfG paulinchen
Logged

Pages: [1]   Go Up
Jump to: