Hallo zusammen,
also irgendwie habe ich Probleme einen TCP Verbindung aufzubauen.
Mein Atmel hat einen TCP/IP Stack implementiert.
Eine kleine Anwendung auf dem µC soll nun eine Verbindung über TCP mit
einem Java Programm auf dem Rechner aufbauen.
Dies funktioniert soweit auch. Egal wer die Verbindung initiiert.
Beginne ich den Handshake nun vom Java Programm antwortet der µC promt
und das Java Programm antwortet wiederum mit einem Ack.
Beginne ich ein SYN vom µC zu senden, kommt erst nach einem
undefinierten späteren Zeitraum ein SYN/ACK vom Java Programm zurück
welches sich definitiv in der ServerSocket.accept() Funktion befindet.
Auf dem angehängten Bild antwortet der µC auf das erste (nach vielen
vergeblich gesendeten SYN) SYN/ACK aus irgend einem Grund nicht. Dies
muss ich noch herausfinden wieso... jedoch komisch ist, dass erst nach
einem RST welches vom JAVA Programm kommt alles direkt funktioniert.
Hat ein RST bei einem Handshake irgend eine Bedeutung?!? Ich wüsste
nicht welche.
Die Verbindung kommt immer zustande. Jedoch mal schnell mal sehr spät.
Hat jemand ne Ahnung ob das auch am Java Programm liegen kann? Erwartet
die accept Funktion des ServerSockets irgend einen besonderen
Optionsparameter des TCP Packets?
192.168.2.101 ist der µC und 192.168.2.100 der PC mit dem Java Proramm.
Die Routine im µC zum Aufbauen einer TCP Verbindung sieht folgendermaßen
aus:
Im Prinip geht hier hervor, dass 5 mal versucht wird alle 2,5 sekunden
ein SYN zu senden und dann aktiv auf eine Antwort gewartet wird.
Weitere verbindungversuche kommen dadurch zustande, dass die Routine
darüber diese obige immer wieder aufruft bis es klappt.
Hoffe jemand kann mir weiterhelfen... ich hänge hier schon eine ganze
Weile.
Vielen Dank für eure Mühe!
Tobi
weil die meisten TCP-Stacks eingehende Pakete anhand ihrer Portnummer
auch für bereits geschlossenen Verbindungen zuordnen (für eine gewisse
Zeit).
Einfach in einem Bereich die Portnummer bei jeder neuen Verbindung um
eins erhöhen - wenn du mal schaust wie der PC das macht wirst du das
selbe Muster feststellen.
Sascha
super danke für euren Tip!!!
Jetzt funktioniert es um einiges besser!!
Komisch ist nur das manche SYN/ACK nicht direkt erkannt werden, aber das
bekomm ich auch noch hin.
Komisch ist auch das das Java Programm beim Beenden der Verbindung nicht
nur ein Fin/ACK sendet sondern davor auch noch ein PSH/ACk mit eine
Datenbyte das 0 ist.... komisch... naja...
Danke euch!!
>nur ein Fin/ACK sendet sondern davor auch noch ein PSH/ACk mit eine>Datenbyte das 0 ist.... komisch... naja...
Nope. Nicht komisch.
Ordentliche TCP/IP Stacks puffern Daten im Kernel zwischen und ein
Betriebssystem darf schonmal warten, ob es nicht noch auf ein
weiteres zeitnahes Paket spekulieren mag. Mit dem PSH gibt eine
remote Applikation den "Hinweis", dass es nunmehr ein guter
Zeitpunkt waere, die Daten an die lokale Applikation
weiterzugeben.
>Komisch ist nur das manche SYN/ACK nicht direkt erkannt werden, aber das>bekomm ich auch noch hin.
Reine Glaskugelvermutung: es riecht nach einem (reverse) DNS Timeout.
-Balu
Hallo Balu,
danke für deine Infos,
das bedeutet, dass mein Java Programm mir nur mitteilen möchte ich solle
noch etwas senden wenn ich dies möchte da sonst das Beenden der
Verbindung folgt?!?
Aber wieso triggert mich das Programm an... wenn ich etwas zu senden
habe würde ich das doch ohnehin tun?!?
Bzw mir ist nicht ganz klar wie ich auf das Datenpaket reagieren soll.
Ich hab meine Implementation zur Zeit soweit, dass ich jedesmal einen
Autoreply auf ein Datenpaket sende. (Java Programm ist ein kleiner TCP
Chat)
Egal was ich mit dem Java Programm sende, sendet mein Atmel immer ein
"Hallo" zurück.
Nun kommt aber diese blöde Datenpaket am Ende der Verbindung (aber auch
nicht jedes mal) und bringt das Ende durcheinander.
Mein Atmel sendet dann ein ACk auf das Datenpaket mit dem Dateninhalt
"0" vom Java Programm und dann ... je nachdem wie es zeitlich hinkommt
meist sendet das Java Programm ein FIN/ACK direkt vor meinem Autoreply
der dann logischerweise nicht mehr beantwortet wird.
Ich könnte ja sagen, ein Datenpaket mit Inhalt "0" wird generell
verworfen.. oder wie handhabt man dieses Paket üblicherweise??
Hab ja nun einen Zufallsgenerator für den Sourceport eingebaut.
Komisch ist allerdings immernoch, dass es oft ewig dauert bis auf mein
SYN eine Bestätigung kommt. Manchmal geht es aber ganz fix. (besser wie
immer mit dem gleichen Port) ... Das mit dem DNS Timeout hab ich noch
nicht ganz rausgefunden Balu. Meinst du ich müsste evtl einen DNS Client
implementieren damit das funktioniert?
Wieso aber funktioniert es in die andere Richtung einwandfrei?
Hier nutze ich immer die gleichen Ports und der Three Way Handshake
funktioniert verdammt schnell... hm..
Danke euch!!!
Tobi
>das bedeutet, dass mein Java Programm mir nur mitteilen möchte ich solle>noch etwas senden wenn ich dies möchte da sonst das Beenden der>Verbindung folgt?!?
Du meinst das PSH-Flag? Grob kannst Du Dir das als (java.io)-
flush()-Netzwerk-Entsprechung vorstellen. (Keine Ahnung,
ob das im Programm steht oder von der Java-Laufzeitumgebung
erzeugt wird, normalerweise "stört" ein PSH-Flag nicht)
>Mein Atmel sendet dann ein ACk auf das Datenpaket mit dem Dateninhalt>"0" vom Java Programm und dann ...
Ein "leeres ACK" bestätigt die bis dahin (vom *TCP*-Netzwerkstack)
empfangenen Daten. Hmm... Die meisten lightweight
embedded-"Netzwerkstacks" verlagern Teile der TCP state machine
ins Applikationsprogramm... d.h. ohne die Lektüre und das saubere
Umsetzen der TCP state machine wird das nicht konform umgesetzt
werden können.
>Hab ja nun einen Zufallsgenerator für den Sourceport eingebaut.>Komisch ist allerdings immernoch, dass es oft ewig dauert bis auf mein>SYN eine Bestätigung kommt.
Ich nehme an, Du verwendest Linux. In diesem Moment mit "netstat -ant"
ansehen, in welchem Zustand der Socket unter dem Java-Rechner ist (jetzt
waere die Kenntnis der TCP state machine wichtig ;-) (Unter Windows
wird es ein analoges Kommando geben...)
Vorschlag:
Auf einem zweiten Rechner die Funktionalität des AVRs nachbilden.
Das sollte in einem 30-Minuten-Hack zu schaffen sein. Geht nun der
ursprüngliche Java Rechner "ordentlich" ?
Mit einem frisch gestarteten Java-Rechner ein
"nslookup <ip-des-embedded-AVRs>" eingeben. Ist das Ergebnis gleich
da oder musst Du aehnlich lange warten wie auf das SYN-ACK?
DNS hat ein Feature names negative Caching, d.h. man darf sich auch
merken, dass ein DNS Aufruf keine Ergebnisse liefert(z.B. timeout). Dann
gibt es das zweitemal natürlich sofort ein (negatives) gecachtes
Ergebnis... Wenn etwa gleiche Zeiten: ist da irgendwo logging mit
symbolischen Namen angeschaltet?
-Balu
Hallo
ich weiß der Beitrag ist schon ein bisschen älter, aber ich wollte mal
mein Glück versuchen.
Ich arbeite momentan an einem eigenen Projekt(chen) und einen HTTP
Request an einen Server senden, es gibt jedoch keine Beispiele für einen
HTTP Client. Es wäre schön wenn ich mir deinen AVR code mal anschauen
könnte
lg