Hi,
ich habe ein Serial-to-Ethernet-Wandler, mit dem ich einen URL senden
möchte. Ich habe mal mit Wireshark geschaut, was bei dem URL-Senden vom
Browser gesendet wird. Diese Daten (Header und Anforderungs-String) habe
ich dann im Quelltext kopiert und nacheinander auf dem UART gesendet:
Aber die angesprochene IP-Adresse reagiert nicht. Im Wireshark sehe ich
kurioserweise auch nicht die Anforderung des URL, die ich gesendet habe.
Auf dem UART gehen aber die Daten raus. Ist im Quellcode etwas
unvollständig oder falsch?
Die Infos im Header sind mir nicht verständlich, was für eine genaue
Bedeutung haben die?
Matthias schrieb:> ich habe ein Serial-to-Ethernet-Wandler, mit dem ich einen URL senden> möchte.
Welchen genau? Viele Wandler haben ein Manual wo man genau nachlesen
kann wie sie angesprochen werden möchten.
Den Ethernet Header sendet man normalerweise nicht mit, muss dafür aber
irgendwie die Zieladresse angeben. Normalerweise läuft auf dem UART ein
Protokoll.
Ja, ich möchte die IP-Adresse 192.168.178.53 damit ansprechen.
Ich habe einen Lantronix X-Port Artikel-Nr.: XP1002000-05R). Der ist so
konfiguriert, daß eigentlich alles 1:1 rein und raus geben sollte. Das
Senden einer Test-HTML-Seite geht damit, aber die URL-Anforderung geht
nicht raus.
Ich habe mal kurz das Users-Guide durchgeblättert und wenn ich das
richtig sehe, geht das höchstens über die Modem-Emulation mit entspr
AT-Kommandos(ATDT zum Verbindungsaufbau, etc) - erst danach kannst du
die HTTP-Kommunikation durchführen (+++ATH zum Verbindungsabbruch).
> höchstens über die Modem-Emulation
Scheint, dasses noch eine andere Methode gibt - schau mal unter "Manual
Connection" (S. 52ff); könnte sein, dass das deinen "caHeader" erklärt.
Beitrag "HTTP Request (Wie kann ich es machen?)"
Da hat schon mal jemand eine ähnliche Frage gehabt. Nämlich den XPort
als Seriell<->TCP Brücke verwendet und will einen GET-Request senden.
Aber leider steht dort nicht, ob es am Ende geklappt hat.
Nach dem letzten Header musst du eine leere Zeile "\r\n" senden.
Ich würde dir empfehlen, das HTTP/1.0 Protokoll zu benutzen, denn
ansonsten kann es dir passieren, dass der Server die Antwort in Chunks
zerlegt, die du decodieren und zusammenfügen musst.
> Accept-Encoding: gzip, deflate
Das willst du mit wahrscheinlich nicht, oder kann dein Programm
komprimierte Streams dekomprimieren?
Schau dir Kapitel 10 in
http://stefanfrings.de/mikrocontroller_buch/Einstieg%20in%20die%20Elektronik%20mit%20Mikrocontrollern%20-%20Band%202.pdf
an, da wird das HTTP 1.0 Protokoll so weit erklärt, wie man für
Mikrocontroller-Anwendungen typischerweise braucht.
Ich habe nun etliches den ganzen Tag ausprobiert und mich versucht
einzulesen in das Thema. Aber ich muß ehrlich gestehen, daß ich total
verwirrt bin. Ich habe gedacht, wenn ich das selbe sende wie der Browser
beim GET, dann wird der Server schon antworten. So einfach ist es leider
nicht.
Ich denke das mit dem GET und Host wird schon richtig sein, aber da muß
doch sicherlich noch etwas vorher gesendet werden. Mir ist aber nicht
ganz klar, was.
1
voidhttp_Request(void)
2
{
3
unsignedintuiAnzahlBytes;
4
5
strcpy(caString,"GET /login.htm HTTP/1.1\r\n");
6
strcat(caString,"Host: 192.168.178.53\n\n");// server
Spricht was dagegen, als Host hier ebenfalls "192.168.178.53" anzugeben?
Das muß doch beides mal der selbe Host sein, oder?
Ich hoffe es ist nur eine Kleinigkeit, die mir bis zum Erfolgserlebnis
fehlt...
Langsam bin ich mir nicht sicher, ob der XPORT die Daten tatsächlich als
Bridge 1:1 durchreicht. Aber wie kann ich testen, das tatsächlich aus
der RJ45 kommt? Wireshark wird vermutlich nur was anzeigen, wenn es sich
um einen "gültigen" Befehl handelt. Vermutlich brächte ich noch einen
zweiten XPort, den ich mit gekreuztem Kabel anschließe und dort die
Daten mitlese.
Matthias schrieb:> Ich habe nun etliches den ganzen Tag ausprobiert und mich versucht> einzulesen in das Thema. Aber ich muß ehrlich gestehen, daß ich total> verwirrt bin. Ich habe gedacht, wenn ich das selbe sende wie der Browser> beim GET, dann wird der Server schon antworten. So einfach ist es leider> nicht.
Doch ist so, aber da fehlt hat noch die leere Zeile am Ende. Solange du
die nicht sendest, wartet der Server auf weitere Request header.
> aber da muß doch sicherlich noch etwas vorher gesendet werden.> Mir ist aber nicht ganz klar, was.
Lies das PDF, dass ich dir empfohlen habe. Da steht drin, worauf es
ankommt.
> Serial.print("GET /~username/scraper.php HTTP/1.1\n");> strcat(caString, "Host: 192.168.178.53\n\n");> Serial.print("HOST: www.myserver.com\n\n");
Es muss immer \r\n heißen. Ob und wie ein Server auf falsche
Zeilenumbrüche reagiert, ist nicht spezifiziert.
> Langsam bin ich mir nicht sicher, ob der XPORT die Daten> tatsächlich als Bridge 1:1 durchreicht.
Richte dir einen lokalen Webserver ein und kontrolliere die
Kommunikation mit Wireshark.
Oder benutze Netcat um auf einen einzelnen Request zu warten. Wie das
unter Linux aussieht, wenn ich im Browser http://localhost:8080/test
aufrufe, habe ich als Bild angehängt.
Nachtrag: Warum wiederhole ich hier eigentlich die Infos aus meinem
eigenen PDF? Ich hatte es geschrieben, um genau dies nicht tun zu
müssen.
@Stefan: zunächst mal Danke für Deine Hilfe!
OK, ich habe nun zweimal "\r\n\r\n" nach dem Hostname, hatte ich zuvor
auch schon mal ausprobiert, geht aber immer noch nicht:
Du meinst sicherlich Kapitel 10.1. Aber das sind ja die 2 Zeilen, die
ich sende, nun gefolgt von 2 Zeilenumbrüchen. Irgend wie stehe ich auf
dem Schlauch. Sorry.
Ich benutze aktuell mein neues Ethernetmodul zum Programmieren (Platine
mit STM32). Als Gegenstelle benutze ich zum Testen meinen alten
Webserver (noch mit ATMEGA), den ich vor über 10 Jahren mal programmiert
habe. Er geht problemlos, muß aber nur auf HTTP-Requests entsprechende
HTML-Quellcode senden. GET Senden habe ich bislang nicht gemacht.
Ich werde Netcat mal morgen probieren. Muß mal suchen, wo es dieses für
Windows 10 gibt.
Matthias schrieb:> Ich hoffe es ist nur eine Kleinigkeit, die mir bis zum Erfolgserlebnis> fehlt...
Vom prinzipiellen Schichtaufbau her:
- 5-7 Session/Presentation/Application : HTTP(S)
- 4 Transport : TCP
- 3 Network : IP
- 2 Data Link : Ethernet
Direkt Layer 5 zu Layer 2 geht so nicht.
Du muss dein Teil zumindest dazu bringen überhaupt erstmal eine
TCP-Connection zum Ziel aufzubauen. Erst wenn diese steht "steht" kannst
du in den höheren Layer überhaupt dran denken was zu senden. Ob das
"xport" das alles macht müsstest du im Wireshark sehen können. Wenn es
dumm läuft musst du dich im Layer 3 auch noch um die MAC-Adressen und so
kümmern oder gar einen kompletten Frame zusammensetzen.
-
https://de.wikipedia.org/wiki/Transmission_Control_Protocol#Verbindungsaufbau
- .
- https://de.wikipedia.org/wiki/IP-Paket#IP-Header
-
https://de.wikipedia.org/wiki/Transmission_Control_Protocol#Aufbau_des_TCP-Headers
Matthias schrieb:> Irgend wie stehe ich auf dem Schlauch. Sorry.
Teste das mal manuell mit Netcat ganz unabhängig von deiner Elektronik.
Im Angehängten Bild habe ich Google als Webserver aufgerufen. Du kannst
das ebenso mit deiner IP Adresse machen.
Matthias schrieb:> Muß mal suchen, wo es dieses für Windows 10 gibt.
Weil es immer wieder woanders ist, habe ich eine Kopie davon auf meine
eigene Homepage gepackt:
http://stefanfrings.de/avr_tools/netcat-win32-1.12.zip
Korrektur:
> Teste das mal
Ich meinte, dass du den Web-Server manuell testen sollst. Es bringt ja
nichts, einen Web-Client zu programmieren, solange nicht klar ist ob und
wie der Server funktioniert.
Die große Frage ist, welche Protokollschichten vom
Serial-to-Ethernet-Wandler abgewickelt werden.
https://www.ip-insider.de/was-ist-das-osi-modell-a-605831/
Gibt es keine Unterlagen und/oder Programmbeispiele zum
Serial-to-Ethernet-Wandler?
Wie werden die einzelnen Protokollschichten parameterisiert?
z.B. MAC?
Matthias schrieb:> strcat(caString, "Host: 192.168.178.53\n\n"); // server
Die Kombination "\n\n" sendet schon eine weitere Leerzeile nach
"Host:...". Stefan hat das wohl übersehen. Trotzdem würde ich an Deiner
Stelle konsequent CRLF-Paare schicken, also:
1
strcat(caString,"Host: 192.168.178.53\r\n\r\n");// server
wie Du es auch später dann probiert hast. Lass das so, das sieht gut
aus. Dann wird gesendet:
1
GET /login.htm HTTP/1.1<CR><LF>
2
Host: 192.168.178.53<CR><LF>
3
<CR><LF> (also Leerzeile)
Das passt! Aber vorher(!) musst Du natürlich eine TCP-Verbindung
aufbauen. Sonst weiß Dein Gerät ja gar nicht, wohin es diese Zeilen
überhaupt schicken soll. Diese Host-Zeile gehört zum HTTP-Protokoll und
wird von Deinem Serial-Ethernet-Wandler überhaupt nicht inhaltlich
ausgewertet!
Von daher ist diese Bemerkung:
> Auf der Seite https://www.tigoe.com/pcomp/code/PHP/25/#more-25 hat mich> verwirrt, daß er erst mal einen Server mit dem XPort connected hat:
wichtig! Du musst erst den Connect machen. Dabei solltest Du die
IP-Adresse 192.168.178.53 verwenden - wenn das Dein HTTP-Server ist, den
Du erreichen willst.
1
>voidxportConnect(){
2
>// send out the server address and
3
>// wait for a "C" byte to come back.
4
>// fill in your server's numerical address below:
5
>Serial.print("C192.168.1.23/80\n");
6
>status=connecting;
7
>}
Im Kommentar lese ich auch, dass Du auf ein "C" (wie "Connected") warten
sollst. Von daher ist die obige Funktion nicht wirklich vollständig. Es
kann natürlich sein, dass der Code nach Aufruf von xportConnect() diese
Abfrage macht. Ich kenne diesen Code nicht.
> Bei mir kommt da keine Rückmeldung, wenn ich "C192.168.178.53/80\n"> sende.
Das ist schlecht. Ich sehe aber überhaupt keine Abfrage, um die Antwort
des Geräts auszuwerten, siehe oben. Welche IP hat denn Dein Gerät?
Stimmen die ersten 3 Oktetts überein?
> Spricht was dagegen, als Host hier ebenfalls "192.168.178.53" anzugeben?
Die Zeile "Host: ...." gehört zum HTTP-Protokoll und sagt dem Server
lediglich, dass die URL insgesamt "http://192.168.178.53/" lauten soll.
Es gibt Webserver, die arbeiten mit virtual Hosts und können auf
verschiedene IP-Adressen oder verschiedene Namen auch verschiedene
Seiten ausliefern. Nichts anderes bedeutet hier die Host-Zeile. Du
solltest daher entweder den Hostnamen Deines Webservers oder die
IP-Adresse angeben. Man kann sogar für erste Tests auf die Host-Zeile
verzichten, allerdings muss man trotzdem eine weitere Leerzeile nach
"GET ..." schicken, also das weitere Paar "\r\n". Dann nimmt der Server
an, Du meinst den Standard Virtual Host ("Default").
Viel wichtiger ist der Connect auf TCP/IP-Ebene, also der
"C192.168.178.53\n"-Befehl. Ob der jedoch syntaktisch richtig ist, kann
ich nicht beurteilen, denn ich kenne Dein Xport-Gerät nicht.
Du hast massive Lücken bei dem Verständnis von IP, TCP/IP und HTTP - in
dieser Reihenfolge. Lies Dich erstmal in die Thematik ein, bevor Du da
im Nebel stocherst. Es ist nicht verkehrt, die Protokolle auch zu
verstehen und zu beherrschen, statt diese einfach nur blind und falsch
anzuwenden.
Und dann noch als Letztes:
Lies auch die Dokumentation zu Deinem Serial-to-Ethernet-Wandler! Dort
wird es nicht nur Beispiele geben, sondern da wird bestimmt auch
erklärt, wie Du vorgehen musst, um Dich mit einem Server zu verbinden.
Die Beispiele solltest Du ausprobieren und auch versuchen, zu verstehen.
Sonst wird das nix.
Gerald K. schrieb:> Gibt es keine Unterlagen und/oder Programmbeispiele zum> Serial-to-Ethernet-Wandler?
Unter https://www.lantronix.com/products/xport/ findet man einige
Dokumente. Aber ehrlich gesagt verstehe ich nicht alles so ganz...
Auf https://cdn.lantronix.com/wp-content/uploads/pdf/XPort_UG.pdf steht
auf Seite 52 was von "Active Startup". Mein X-Port ist wie folgt
eingestellt:
Das Register steht auf "0xD4":
- Incoming Connection: Always Accept
- Response: Character response (C=connect, D=disconnect, N=unreachable)
- Active Startup: Manual connection
Das mit dem Senden von "C192.168.178.53/80\n" sollte daher eigentlich
gehen. Nur es kommt keine Antwort vom X-Port zurück.
Vergiss vorläufig deinen XPort, teste das erst manuell mit Netcat.
1
> nc -v 192.168.178.53 80
2
Connection to 192.168.178.53 80 port [tcp/http] succeeded!
Bekommst du damit eine Verbindung zum Server? Wenn nicht, ist der Server
oder die Verbindung dorthin kaputt. Oder der IP/Port sind falsch.
Wenn verbunden, gebe dann das ein:
1
GET /login.htm HTTP/1.0<Enter>
2
<Enter>
Dann müsste eine HTML Seite oder wenigstens eine Fehlermeldung zurück
kommen. Wenn nicht, ist der Server kaputt.
Matthias schrieb:> Unter https://www.lantronix.com/products/xport/ findet man einige> Dokumente.
Das Teil kann zumindest schon mal einiges:
Network Interface
- Interface: Ethernet 10Base-T or 100Base-TX (Auto-Sensing)
- Protocols: TCP/IP, UDP/IP, ARP, ICMP, SNMP, TFTP, Telnet, DHCP, BOOTP,
HTTP, and AutoIP
Management
- SNMP, Telnet, serial, internal web server, and Microsoft Windows®-
based utility for configuration
Aus dem Handbuch:
Assigning an IP Address
The unit’s IP address must be configured before it can work correctly on
a network. You have several options for assigning an IP to your unit. We
recommend that you manually assign the IP address over the network using
DeviceInstaller.
usw...
Hast du das Teil überhaupt richtig Konfiguriert? Kannst du es von einem
anderen Gerät aus erreichen?
Stefan ⛄ F. schrieb:> Vergiss vorläufig deinen XPort, teste das erst manuell mit Netcat.
Danke Dir für Deine Hilfsbereitschaft!
Ich habe nun Netcat von Dir verwendet. Wenn ich die Daten so eingebe,
geht das Fenster sofort nach Drücken der Entertaste zu. Ohne das ">" zu
beginn, dauert es 1-2 Sekunden, bevor das Fenster verschwindet. Stürzt
da was ab oder soll das Absicht sein?
DIE GUTE NACHRICHT:
Das connecten geht nun. Ich habe mich selbst verarscht, das
Empfangsarray wurde an anderer Stelle versehentlich an ein paar Stellen
modifiziert. Nach dem Booten kommt ein "D" und nach dem Connecten nun
auch ein "C", wie es sein soll.
Öffnet zuerst ein Fenster "Eingabeaufforderung" und tippe dort die
netcat Befehle ein. Dann schließt es sich nicht und dann kannst du die
Ergebnisse sehen.
> Ohne das ">" zu beginn
Das sollst du nicht eingeben, das ist die Eingabeaufforderung (von
Linux) das ich bitte einen Befehl eingeben soll. Gibt's bei Windows auch
so ähnlich.
Schön dass es nun trotzdem klappt, solche Rückmeldungen werden oft
vergessen.
Matthias schrieb:> Ohne das ">" zu beginn
Du hast damit ziemlich sicher versehentlich eine Datei "nc" (ohne
Endung) im aktuellen Verzeichnis angelegt. Größe: 0 Bytes.
Die kannst Du wieder löschen.