Ethernet Library blockiert Pins (außer 13, 12, 11, 10) ?!?!

Das Problem mit String Konstanten/Literalen ist folgendes:

Der AVR hat eine modifizierte Harvard Architektur. Es gibt getrennte Daten- und Adressbusse für ROM und RAM und die zwei Adressräume sind größtenteils getrennt. Das heißt anders als bei der klassischen von-Neumann Architektur können normale Befehle nicht so einfach ins ROM/Flash greifen. Bei Konstanten wird das dadurch umgangen, dass diese beim Start alle vom Flash ins RAM kopiert werden. Anders als man also vielleicht denkt landen die alle im RAM und davon gibt es auf dem UNO nicht viel.

Auf Assembler-Ebene gibt es aber ein paar Befehle um Daten aus dem Flash auszulesen. Auf C-Ebene stehen dafür Makros wie PSTR() und PROGMEM zur Verfügung. Dazu ein paar Funktionen um Daten aus dem Flash zu kopieren und die _P Version der String Funktionen um direkt Flash Strings zu verarbeiten. Dazu kommt von der Arduino IDE das F() Makro, welches mit print() und println() geht.

Das F() Makro reicht in vielen Fällen um die größten Strings aus dem RAM entfernen, da das eben oft print() Anweisungen sind (geht übrigens auch mit deinen Serial Ausgaben!). Aber man kann hier und da auch weiter optimieren.

Es gibt auch eine Funktion um den freien Speicher anzuzeigen:

int getFreeRAM() 
{
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

Geht aber natürlich nur wenn er noch nicht total voll ist.

Doofe frage neben bei... was macht die strstr string Funktion eigentlich..?

strstr() such einen Teil-String in einem String. Sie gibt NULL zurück wenn der String nicht gefunden wurde und einen Zeiger auf den Anfang des Teil-Strings wenn dieser enthalten ist:
http://www.nongnu.org/avr-libc/user-manual/group__avr__string.html#ga6a441da9211eb85881d99c60b1003552

http://www.cplusplus.com/reference/cstring/strstr/

Ersteres ist die AVR libc. Das ist alles was auf dem AVR vorhanden ist. Die zwei anderen Links sind Standard C. Die Standard C Lib ist ähnlich aber nicht 100%ig identisch

Das mit dem Zeiger auf den Teil-String wird hier ausgenutzt:

(strstr(clientline, " HTTP"))[0] = 0;

Sowie ich das verstehe terminiert das den String am Anfang des "HTTP". Alternativ könnte man den Zeiger auch mit * dereferenzieren. Das ist hier etwas verwirrend geschrieben, da der Zeiger den die Funktion liefert nicht extra abgespeichert wird.