Forum: Mikrocontroller und Digitale Elektronik TCP Verbindung zu langsam


von Anderle K. (anderl)


Angehängte Dateien:

Lesenswert?

Hallo miteinander,
ich benutze den Stm32F4, sample (32bit Werte) Daten mit einer Datenrate 
von 192kHz und würde diese dann genre über TCP an meinen PC schicken 
(Matlab socket). Die Übertragung ist leider viel zu langsam. Meint ihr 
es ist prinzipiel möglich ca 800 kByte pro Sekunde zu versenden?

Im Moment habe ich einen Speicher angelegt der für ca. 20ms (17600 
bytes) reicht. Diesen sende ich dann.
In Wireshark sieht das wie folgt aus: (siehe Anhang). Jedes Packet hat 
1440 bytes. Nach zwei Packeten (2880) wird geACKed. Ist es auch möglich 
iwie erst nach 17600 Bytes zu ACKen? Wie wären da die Fachausdrücke für 
die Einstellungen? Mein Ziel ist es diese 17600 Bytes möglichst schenll 
auf den PC zu bringen um dann wieder von vorne anzufangen. Im Moment 
dauert das ganze über eine Sekunde (siehe Anhang)

Was ich nicht verstehe ist folgendes: (siehe Anhang)

Daten 1440bytes
95ms Pause
Daten 1440bytes
<1ms Pause
ACK
5ms Pause
Daten 1440bytes
95ms Pause
.
.
.

Kann sich jemand einen Reim darauf machen warum das eine Paket immer so 
lange braucht (95ms)?
Ich würde mich sehr freuen wenn mir jemand ein paar allgemeine Dinge 
(Einstellungen) über TCP sagen kann die für das schnelle Versenden von 
Daten wichtig sind.

Vielen vielen Dank schon mal

von S. R. (svenska)


Lesenswert?

TCP ist fuer Echtzeitanwendungen eher ungeeignet. Nimm UDP.

Der STM32 ist der Sender. Pakete, die noch nicht bestätigt wurden, darf 
der nicht wegwerfen, also muss der TCP-Stack(!) dort 100ms puffern 
können. Stelle die Window-Size hinreichend groß ein, damit effektives 
Pipelining möglich wird. uIP kann kein ordentliches Windowing. Stelle 
außerdem sicher, dass du eine Vollduplexverbindung hast, sonst 
zerschießen dir die ACKs deine Datenpakete.

Oder nimm einfach UDP.

von Anderle K. (anderl)


Lesenswert?

Danke für die schnelle Antwort.
Ich benutze den IP Stack von Keil. Dort kann ich leider nur die Receive 
Window size einstellen. Ist gerade auf 8640 bytes eingestellt. Receive 
window size sollte aber nichts damit zu tun haben oder?
Ich habe ein Funktion (TCP_send) die nimmt einen Buffer und verschickt 
diesen. Dafür muss der Socket bereit sein. Keil schreibt dass der socket 
bereit ist wenn der letzte frame geACKt wurde.
Somit ist ja eigentlich kein pipelining möglich oder? Oder ist 
pipelining hier schon dass er immer zwei Frames sendet und erst dann 
geACKt wird? Kann man auch drei Frames einstellen.
Keil sagt es handelt sich bei dem Socket um eine Voll duplex Verbindung.
Kann ich mich darauf verlassen oder gibt es eine Möglichkeit das 
nachzuprüfen?
Das ACK kommt ja direkt nach dem zweiten Frame. Warum muss er es dann 
solange buffern. Warum die Verzögerung nur bei einem Frame? Versteh ich 
leider nicht

Vielen vielen Dank für jede Antwort

von Pandur S. (jetztnicht)


Lesenswert?

Naja. Wenn ein Frame nicht bestaetigt wird, wird es nochmals versandt. 
TCP eben.

von (prx) A. K. (prx)


Lesenswert?

Könnte eine Eigenschaft des IP-Stacks sein. Wenn der ähnlich simpel 
arbeitet wie uIP, dann liegt diese Verzögerung im Verfahren vom Stack 
begründet. Da ich den Keil-Stack nicht kenne, schildere ich mal das 
Problem von uIP:

Das hat nur Puffer für einen Frame. Bevor der nicht acked ist geht kein 
nächster raus. Normale TCP Verbindungen schicken aber aus ökonomischen 
Gründen nicht für jeden Frame ein Ack. Jedenfalls nicht sofort, sondern 
verzögert, wenn eine Weile lang nichts kam.

Die Wiznet-Chips haben je nach Pufferkonfiguration ein ähnliches 
Problem. Und lösen es, indem sie den gleichen Frame zweimal unmittelbar 
hintereinander senden. Das frisst zwar doppelte Bandbreite, liefert aber 
sofort ein Ack. TCP mit der Brechstange.

Das hier sieht zwar nicht direkt nach diesem beiden Verfahren aus, weil 
die Seq# fortschreitet, könnte aber damit verwandt sein.

von Jim M. (turboj)


Lesenswert?

Anderle K. schrieb:
> Das ACK kommt ja direkt nach dem zweiten Frame. Warum muss er es dann
> solange buffern. Warum die Verzögerung nur bei einem Frame? Versteh ich
> leider nicht

Moderne Betriebssysteme optimieren die TCP Verbindung. Das bedeutet 
leider auch dass sie erst nach dem 2. Paket ein ACK senden. Damit muss 
der µC IP Stack klar kommen, sonst wirds langsam.

AFAIK kann man als fiesen Hack auch die TCP Pakete einfach doppelt 
aussenden,
das ist aber eher nicht im Sinne der Erfinder.

Aber wieso schreibst das hier und nicht dem Keil Support..?

von Anderle K. (anderl)


Lesenswert?

Das ist mir schon klar. Es geht mir darum dass zwischen datenframe 1 und 
Datenframe2 95 ms delay sind. Nicht aber zwischen Datenframe2 und 
Datenframe1

Datenfram1 1440bytes
95ms Pause
Datenframe2 1440bytes
<1ms Pause
ACK
5ms Pause
Daten 1440bytes
95ms Pause
.
.
.

von (prx) A. K. (prx)


Lesenswert?

TCP sollte man nur dort verwenden, so man wirklich den Datenstrom in 
seiner vorständigen Form benötigt, und dabei gewisse Stolperer und 
Verzögerungen akzeptiert.

Wenn es hingegen darauf ankommt, stets den letzten Stand zu haben und 
ggf. bei Problemen mal eine Lücke bleiben darf, dann ist UDP das 
Protokoll der Wahl und TCP ungeeignet.

von Jojo S. (Gast)


Lesenswert?

es muss aber nicht jeder Frame quittiert werden, der Empfänger hat ja 
eine WindowSize von ca. 64k gemeldet.
Probiere mal die TX_BUF Anzahl in ETH_STM32F4XX.H auf 3 oder 4 zu 
setzen. Wenn das richtig implementiert ist sollte das ein Ringbuffer 
sein und mehrere Frames gesendet werden können.
TCP ist schon schnell genug, es ist nur ineffizient bei kleinen 
Datenpaketen und Ping-Pong Quittierung. Und der Empfänger kann den 
Sender anhalten wenn er sein Puffer voll läuft, dann geht dir Echtzeit 
flöten.

von Stefan F. (Gast)


Lesenswert?

> Somit ist ja eigentlich kein pipelining möglich oder?

Ja, scheint so zu sein.

Clients können die Option TCP_NODELAY setzen (wenn du den Quelltext 
hast), damit das ACK schnellstmöglich gesendet wird. Unter Windows kann 
das in diesem Fall "Wunder" bewirken.

von Anderle K. (anderl)


Lesenswert?

Jim Meba (turboj)

>Moderne Betriebssysteme optimieren die TCP Verbindung. Das bedeutet
>leider auch dass sie erst nach dem 2. Paket ein ACK senden. Damit muss
>der µC IP Stack klar kommen, sonst wirds langsam.

Ist ja in Ordnung wenn nur jedes zweite Paket geACKt wird. Sind ja 
unmengen an Daten da sodass gleich ein zweites Paket losgeschickt werden 
sollte.

 Jojo S. (jojos)

>TX_BUF Anzahl in ETH_STM32F4XX.H auf 3 oder 4 zu setzen.

Kann ich leider nicht machen. Kann MMS, receive window size, memory pool 
size, core thread stack size, interface thread stack size. Müssten aber 
nach meinem Verständnis alle groß genug gewählt sein.

Freue mich sehr über weitere Vorschläge

von (prx) A. K. (prx)


Lesenswert?

Jojo S. schrieb:
> es muss aber nicht jeder Frame quittiert werden,

Normalerweise nicht. Wenn aber der Sender wenig Pufferkapazität hat, 
dann muss er auf Ack warten, bevor er die davon bestätigten Daten aus 
dem Puffer verwirft.

von Anderle K. (anderl)


Lesenswert?

Stefan U. schrieb:
> Clients können die Option TCP_NODELAY setzen (wenn du den Quelltext
> hast), damit das ACK schnellstmöglich gesendet wird.

Ein Matlab Socket ist mein Client. Kannst du mir sagen wie man sowas 
einstellen kann? Kann man das in Matlab einstellen oder muss sowas 
direkt unter Windows vorgenommen werden? Habe leider nichts gefunden.

Dankedanke

A. K. schrieb:
> Normalerweise nicht. Wenn aber der Sender wenig Pufferkapazität hat,
> dann muss er auf Ack warten, bevor er die davon bestätigten Daten aus
> dem Puffer verwirft.

Ich kann die ETH memory pool size auf bis zu 100kbyte setzen. Das sollte 
doch die Pufferkapazität sein oder? Leider ändert mehr Speicher da gar 
nichts

von Anderle K. (anderl)


Lesenswert?

Jojo S. schrieb:
> TCP ist schon schnell genug, es ist nur ineffizient bei kleinen
> Datenpaketen und Ping-Pong Quittierung.

Habe aber keine kleinen Datenpakete. Größer als 1440 dürfen sie ja nicht 
werden oder?

von Daniel A. (daniel-a)


Lesenswert?

Es gibt mehrere Layer. 1440 ist ungefähr das Maximum einer Ethernet 
frame / eines IP Packets fragments. Aber ein IP Packet kann aus vielen 
Fragmenten bestehen und insgesamt massiv grösser sein. Und TCP Packete 
sind ja in IP Packete verpackt.

von Random .. (thorstendb) Benutzerseite


Lesenswert?

Ich schick mit dem ARM MW TCP Stack auf einem ATSAM3X 1.5MB und mehr per 
UDP rüber zum µC, der das dann decryptet und (buffered) ausgibt. ACK ist 
pro Paket, aber u.U. asynchron zu den Einzelpaketen. Die Pakete sind 
stets kleiner als 1440 Bytes, 1024Bytes Data + Header + TCP/IP Overhead. 
Anwendung im Echtzeitbereich (Lasershow).

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

in einer der letzten c't Zeitschriften war ein Artikel über 
Optimierungen der Parameter bei einer TCP/IP verbindung

von Jan B. (berge)


Lesenswert?

Also selbst dutzende MBit kriegst du mit dem F4 schon hin.
Mein Problem war eher, dass Matlab nicht hinterher kam ;)

Das "ACK Problem" kann ich bestätigen. Sende noch ein Dummy Paket nach 
deinen Daten um den PC zum senden eines ACKs zu kriegen. Sonst wartet 
der uC ein paar 100ms wenn du Pech hast...

von Anderle K. (anderl)


Lesenswert?

Ah cool. Und du hast es dann hinbekommen. Ich verstehe das mit dem 
Dummypaket nicht. Ich habe ja sofort auch wieder genug Daten um ein 
richtiges Paket zu senden. Wo ist den da der Unterschied?

von Anderle K. (anderl)


Lesenswert?

Auch das Dummypacket kann ich ja erst schicken wenn der TCP socket 
wieder bereit ist, was was heißt, dass das vorherige Frame bestätigt 
werden musste. Dann könnte ich ja auch gleich wieder ein richtiges 
schicken.

von Jojo S. (Gast)


Lesenswert?

Das mit dem Dummy oder Frames doppelt schicken klappt nicht wenn du die 
Keil Software benutzt, da müsstest die die Quellen von deren Device 
Treiber haben.
Die Datei die ich genannt hatte müsste in den Libraries liegen, die 
kompletten Quellen von der Keil MW habe ich auch nicht.
Nachtrag:
Das mit den NUM_TX_BUF wird auch nix bringen. Die send_frame() Funktion 
nutzt das, aber die kann nicht die Bremse sein. Der Stack wird ein 
Timeout haben und tatsächlich auf das Ack warten.

von S. R. (svenska)


Lesenswert?

> Ich habe ein Funktion (TCP_send) die nimmt einen Buffer und verschickt
> diesen. Dafür muss der Socket bereit sein. Keil schreibt dass der socket
> bereit ist wenn der letzte frame geACKt wurde.

Ja, das klingt stark nach "Pipelining können wir nicht", denn dafuer 
musst du ein Paket auf die Reise schicken, bevor das letzte Paket 
geACKt wurde.

> Keil sagt es handelt sich bei dem Socket um eine Voll duplex Verbindung.

Ich meinte die Ethernet-Verbindung. Aber vermutlich ist die auch 
vollduplex, und wenn sie es nicht ist, ist das nicht das Problem.

> Ist ja in Ordnung wenn nur jedes zweite Paket geACKt wird. Sind ja
> unmengen an Daten da sodass gleich ein zweites Paket losgeschickt werden
> sollte.

Ja, aber offensichtlich tut Keils TCP-Stack genau das nicht. uIP

> Freue mich sehr über weitere Vorschläge

Entweder, du erklärst Matlab, dass es TCP_NODELAY setzen soll, oder du 
machst es gleich richtig, nimmst also UDP statt TCP.

von Stefan F. (Gast)


Lesenswert?

> Ein Matlab Socket ist mein Client. Kannst du mir sagen wie man sowas
> (TCP_NODELAY) einstellen kann?

Weiss ich nicht.

> Kann man das in Matlab einstellen oder muss sowas
> direkt unter Windows vorgenommen werden?

Bis Windows XP konnte man diese Option als Default aktivieren, indem man 
einen Registry Eintrag ändert. Aber in allen nachfolgenden Windows 
Versionen geht das nicht mehr.

Auch der Ansatz mit dem Dummy Paket funktionierte nach keinen 
Experimenten nur bis Windows XP, danach nicht mehr.

von Anderle K. (anderl)


Lesenswert?

Jan B. schrieb:
> Also selbst dutzende MBit kriegst du mit dem F4 schon hin.
> Mein Problem war eher, dass Matlab nicht hinterher kam ;)
>
> Das "ACK Problem" kann ich bestätigen. Sende noch ein Dummy Paket nach
> deinen Daten um den PC zum senden eines ACKs zu kriegen. Sonst wartet
> der uC ein paar 100ms wenn du Pech hast...

Danke für diesen Hinweis. Das klappt sehr gut. Mit matlab einfach 
regelmäßig einzelne bytes verschicken. Die ACKen dann auch gleich 
automatisch. Jetzt bekomme ich schon einige MBit hin.
Das Problem ist nur die Rate mit der ich die Dummies sende gut 
einzustellen. Sende ich zu schnell vermülle ich das ganze Netzerk und es 
geht nichts mehr.

Es muss doch irgendwie möglich sein den Matlab TCP socket dazu zu 
bringen jedes ankommende Paket sofort zu ACKen.

Hat irgendjemand eine Idee wie man das machen kann.

Stefan U. schrieb:
> Bis Windows XP konnte man diese Option als Default aktivieren, indem man
> einen Registry Eintrag ändert. Aber in allen nachfolgenden Windows
> Versionen geht das nicht mehr.

Das klingt leider schon mal sehr schlecht:( Windows 7. Wäre aber schön 
wenn das auch Plattformunabhängig möglich wäre.

Da muss es doch irgendwas geben

Danke danke schonmal

von Stefan F. (Gast)


Lesenswert?

> Es muss doch irgendwie möglich sein den Matlab
> TCP socket dazu zu bringen jedes ankommende Paket sofort zu ACKen.

Genau dazu dient die gesuchte TCP_NODELAY Option.

Nur sehr wenige Programme haben dazu eine Einstellmöglichkeit - leider.

> Wäre aber schön wenn das auch Plattformunabhängig möglich wäre.

Bei Linux könnte man sich den Kernel patchen :-)

von temp (Gast)


Lesenswert?

Anderle K. schrieb:
> Auch das Dummypacket kann ich ja erst schicken wenn der TCP socket
> wieder bereit ist, was was heißt, dass das vorherige Frame bestätigt
> werden musste. Dann könnte ich ja auch gleich wieder ein richtiges
> schicken.

Dein Stack auf dem Controller wartet aber für jedes Paket auf das ACK. 
Sendet man mehrere verschiedene Pakete ohne ACK hintereinander, muss man 
sich eine Liste der noch nicht betätigten Pakete führen um sie bei 
Bedarf neu zu senden. Das fehlt aber bei einigen der kleineren Stacks. 
Wenn der das ACK völlig ignorieren würde, kannst du gleich UDP nehmen. 
Das gleiche Paket doppelt hat auch die gleiche Sequenznummer und das ist 
was anderes als ein neues Paket. Ich habe den Spass bei mir und dem µIP 
Stack auch implementiert. Wenn mich nicht alles täuscht ist das bei LWIP 
auch nicht besser. Und irgendwo habe ich mal gelesen, dass die Wiznet 
Dinger mit dem delayed ACK auch Probleme haben. Kann das einer 
betätigen?

von Jojo S. (Gast)


Lesenswert?

Das finde ich schon traurig, da tun die HW Hersteller einiges die 
Controller schnell zu machen und dann wird es durch so sparsame SW 
ausgebremst. Auch wenn man jetzt für die Streams UDP nehmen könnte, die 
anderen Protokolle die auf TCP basieren werden ja auch darunter leiden.
Keil SW kostet ja auch eine Kleinigkeit, die nimmt man ja weil man dann 
auch Hersteller Support hat. Hast du den Keil Support schon mal 
angefragt?

von Peter II (Gast)


Lesenswert?

Stefan U. schrieb:
> Genau dazu dient die gesuchte TCP_NODELAY Option.

sicher? Ich war der Meinung es schaltet nur beim Senden das sammeln von 
Daten ab. Es wird damit jedes Byte direkt gesendet und nicht gewartet ob 
noch weiter Daten kommen.
Das das Auswirkung auf das AKC hat, habe ich bis jetzt noch nicht 
gelesen.

von Anderle K. (anderl)


Lesenswert?

Matlab hat die Funktion TransferDelay

mall segments of outstanding data are collected and sent in a single 
packet when acknowledgment (ACK) arrives from the server.

Wenn ich regelmäßig in einer while(1) schleife die Dummies von Matlab 
zum Controller schicke dann müsste das dazugehörige ACK vom Controller 
ja immer in dem nächsten fertigen Datenpaket enthalten sein.

Daraus müsste folgen:
Matlab sammelt seine Dummybytes und versendet diese sofort wenn der 
Controller ein Datenpaket schickt. Dann enthält das Dummypaket direkt 
das ACK für das Datenpaket vom Controller und dieser kann das nächste 
Datenpaket senden was wiederrum das ACK für das Dummypaket enthält

und so weiter

Ist dieser Gedankengang richtig? Folgt daraus das Matlab immer direkt 
die Datempakete ACKt?


% Configuration and connection

t1 = tcpip('10.155.249.100',2000);
t1.InputBufferSize = 30000;
t1.transferDelay='on';

fopen(t1);

lines=1;
k=0;
n=1;
l=1;
dataarray=0;
out=1;


while(n<=lines)
   len1=t1.BytesAvailable
   fwrite(t1,out);   %Dummypaket
   if (len1>0)
       data=fread(t1,t1.BytesAvailable);
       data=int16(data);
       len1=length(data);
       while(k<len1)

           k=k+2;

            if (len1>=k)
                dataarray(l,n)=bitshift(data(k,1),8)+data(k-1,1);
                l=l+1;
            end
       end
       k=0;
       clear data;
   end
   len1=0;

end

von Anderle K. (anderl)


Lesenswert?

Jojo S. schrieb:
> Das finde ich schon traurig, da tun die HW Hersteller einiges die
> Controller schnell zu machen und dann wird es durch so sparsame SW
> ausgebremst. Auch wenn man jetzt für die Streams UDP nehmen könnte, die
> anderen Protokolle die auf TCP basieren werden ja auch darunter leiden.
> Keil SW kostet ja auch eine Kleinigkeit, die nimmt man ja weil man dann
> auch Hersteller Support hat. Hast du den Keil Support schon mal
> angefragt?

Jajajajaja. Aber es geht doch jetzt um TCP! Ein verbindungsorientierter 
Aufbau und die Sicherheit dass auch alle meine Daten ankommen ist doch 
nur von Vorteil. Ausserdem muss es ja möglich sein. Man benötigt doch 
ledigleich einen Socket der direkt ACKt.

von Pandur S. (jetztnicht)


Lesenswert?

> Aber es geht doch jetzt um TCP! Ein verbindungsorientierter Aufbau und die 
Sicherheit dass auch alle meine Daten ankommen ist doch nur von Vorteil.

Nein, ist es nicht. Es kommt auf die Anwendung an. Es gibt Faelle, da 
machen ein paar verlorenen Frames weniger Sorgen wie ein Stottern oder 
unkalkulierbarer Delay. zB bei einer Audio- oder video Uebertragung.
Ebenso bei einer Regelung, oder Steuerung, sofern man zustandslose Daten 
Sendet.
Generell macht UDP bei zustandslosen Daten Sinn.

von Stefan F. (Gast)


Lesenswert?

>> Genau dazu dient die gesuchte TCP_NODELAY Option.
> sicher? Ich war der Meinung es schaltet nur beim Senden
> das sammeln von Daten ab.

Beides. Die Option schaltet den Nagle-Algorithmus ab. Und dieser hat 
zwei Komponenten:

1) In Senderichtung Daten Sammeln, bis ein Paket voll ist.

2) In Empfangsrichtung kein Ack senden, solange noch weitere Daten 
erwartet werden. Notfalls nach einem Timeout doch ein Ack senden.

Und dieser Timeout ist bei Windows inzwischen ca 200ms.

https://support.microsoft.com/en-us/kb/214397

https://msdn.microsoft.com/de-de/library/windows/desktop/ms740476%28v=vs.85%29.aspx

http://blogs.technet.com/b/nettracer/archive/2013/01/05/tcp-delayed-ack-combined-with-nagle-algorithm-can-badly-impact-communication-performance.aspx

http://us.battle.net/d3/en/forum/topic/5578595314

von greg (Gast)


Lesenswert?

A. K. schrieb:
> Die Wiznet-Chips haben je nach Pufferkonfiguration ein ähnliches
> Problem. Und lösen es, indem sie den gleichen Frame zweimal unmittelbar
> hintereinander senden. Das frisst zwar doppelte Bandbreite, liefert aber
> sofort ein Ack. TCP mit der Brechstange.

Naja, Witz-Net eben. Schaut man sich einmal genauer an, was dann mit 
Gelächter endet. Und dann guckt man sich nach einer richtigen Lösung um.

von Tiramisu (Gast)


Lesenswert?

>Beides. Die Option schaltet den Nagle-Algorithmus ab.

Der Nagle sollte dann greifen, wenn Client und Server nicht
im selben Netz stehen. Nagle ist eine WAN-Optimierung.

Wenn das "MATLAB zu langsam" waere waere man es an
heruntergehenden Windowsizes sehen.

von IP (Gast)


Lesenswert?

Boa, sind diese IP-Stacks rottig.

von Daniel A. (daniel-a)


Lesenswert?

Ich Arbeite,wenn ich Zeit habe, an einem eigenen TCP/IP stack, der 
dieses Problem nicht haben wird. Aber meine TCP Implementierung ist noch 
nicht auf einem brauchbaren stand, und das Routing und die Doku fehlen 
noch.

https://github.com/Daniel-Abrecht/DPA-UCS

von IP (Gast)


Lesenswert?

Daniel A. schrieb:
> Ich Arbeite,wenn ich Zeit habe, an einem eigenen TCP/IP stack, der
> dieses Problem nicht haben wird. Aber meine TCP Implementierung ist noch
> nicht auf einem brauchbaren stand, und das Routing und die Doku fehlen
> noch.
>
> https://github.com/Daniel-Abrecht/DPA-UCS

Bitte den ganzen congestion-avoidance Kram nicht vergessen: 
https://en.wikipedia.org/wiki/TCP_congestion-avoidance_algorithm

von temp (Gast)


Lesenswert?

Bei FreeRTos gibt es ja auch schon eine Weile Bemühungen um einen 
eigenen Stack:

http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/index.html

Hat das jemand schon mal benutzt?

von geb (Gast)


Lesenswert?

Zu den Wiznet Chips:
Bei dem W5300 gibt es das delayed Ack Problem definitiv nicht, hab da 
bis 5MByte/s Durchsatz, und benutze es auch sehr erfolgreich in 
Echtzeitsystemen.
Die Qualität der IC's ist allerdings nicht so besonders, da wird wohl 
nicht wirklich viel getestet in der Produktion. So 5% Ausschuss hab ich 
da meistens, und die defekten IC's haben ein oft recht seltsames 
Verhalten.

Grüsse

von Stefan F. (Gast)


Lesenswert?

> Boa, sind diese IP-Stacks rottig.

Du meinst den einen IP-Stack von Windows.

Linux kommat damit nämlich prima klar. Linux merkt, wenn der Sender nach 
jedem Paket auf ein Ack wartet und stellt sich nach wenigen Paketen 
darauf ein.

von S. R. (svenska)


Lesenswert?

Jojo S. schrieb:
> Das finde ich schon traurig, da tun die HW Hersteller einiges die
> Controller schnell zu machen und dann wird es durch so sparsame SW
> ausgebremst.

Wenn du N unbestätigte Pakete auf die Reise schicken können möchtest, 
dann musst du alle N Pakete so lange im Speicher halten, bis sie 
bestätigt wurden - könnte ja sein, dass du das Paket nochmals 
verschicken musst. Auf einem Controller mit wenig RAM fehlt dieser 
Speicher, da kann der TCP-Stack tun was er will.

uIP lässt Retransmissions beispielsweise teilweise in der Anwendung 
implementieren, damit nicht ein einziges Ethernet-Paket im Stack selbst 
gepuffert werden muss.

von Jojo S. (Gast)


Lesenswert?

S. R. schrieb:
> Wenn du N unbestätigte Pakete auf die Reise schicken können möchtest,
> dann musst du alle N Pakete so lange im Speicher halten

das ist richtig, nur mittlerweile haben die µC ja einige zig kB RAM und 
beim STM32F4 werden die Pakete auch direkt da rein und raus gefeuert. 
Das meinte ich damit das die HW Hersteller das gut unterstüzen. uIP gibt 
es ja schon seit Ewigkeiten und ist auf minimalen Speicherverbrauch 
getrimmt, da hatte man noch von sowas wie Cortex M3/M4 geträumt. Und das 
die Keil Lib das für diese Prozessoren besser macht hätte ich schon 
erwartet.
Ist lwIP da auch so lahm? Ich habe damit noch nicht gearbeitet und die 
Doku mal überflogen, meine aber das da ein Sendbuffer eingestellt werden 
kann.

von IP (Gast)


Lesenswert?

Stefan U. schrieb:
> Linux kommat damit nämlich prima klar. Linux merkt, wenn der Sender nach
> jedem Paket auf ein Ack wartet und stellt sich nach wenigen Paketen
> darauf ein.

Oh cool, hast du Beispiel-Traces von Windows und Linux die das Verhalten 
zeigen?

von IP (Gast)


Lesenswert?

Jojo S. schrieb:
> das ist richtig, nur mittlerweile haben die µC ja einige zig kB RAM und
> beim STM32F4 werden die Pakete auch direkt da rein und raus gefeuert.

Einfach nur "feuern" kann schnell kontraproduktiv werden wenn deine 
Strecke anfängt zu verwerfen.

von Jojo S. (Gast)


Lesenswert?

Nur feuern wollte hier auch keiner, es geht ja um TCP. Und genau das 
möchte der TO verwenden und auch kein neues Protokoll erfinden.
Ich würde trotzdem im Keil Stack weiterbohren. Das Verhalten im ersten 
Post ist schon komisch: der Stack sendet ja einen zweiten Frame ohne 
ACK, also muss der erste noch gepuffert sein. Warum wird da 95 ms 
gewartet und dann trozdem ohne ACK gesendet ?

von S. R. (svenska)


Lesenswert?

Jojo S. schrieb:
> S. R. schrieb:
>> Wenn du N unbestätigte Pakete auf die Reise schicken können möchtest,
>> dann musst du alle N Pakete so lange im Speicher halten
> das ist richtig, nur mittlerweile haben die µC ja einige zig kB RAM und
> beim STM32F4 werden die Pakete auch direkt da rein und raus gefeuert.

Das ist mir auch klar. Aber: War das auch schon so, als Keil den 
TCP-Stack implementiert hat? (Linux läuft auch auf einem Cortex-M3, wenn 
man es dazu zwingt. Inklusive TCP-Stack.)

> Nur feuern wollte hier auch keiner, es geht ja um TCP. Und genau
> das möchte der TO verwenden und auch kein neues Protokoll erfinden.

Der TO sollte einfach UDP benutzen (oder zumindest mal ansagen, warum 
das nicht in Frage kommt), denn das ist für das Problem - zumindest mit 
den hier verfügbaren Informationen - wesentlich besser geeignet. Matlab 
kann jedenfalls UDP.

von PittyJ (Gast)


Lesenswert?

Mal meinen Senf dazu:
Bei UDP können Pakete verloren gehen. Es gibt keinen Resend-Mechanismus. 
Den muss man selber schreiben. UDP also nur benutzen, wenn man sich es 
leisten kann, ab und zu auch ein Paket zu verlieren.

Windows kann mit TCP locker 200MBytes/Sekunde empfangen. Genau das mache 
ich gerade hier. (Arm -> PC, 10G Netzwerk Karten). Es liegt wohl nicht 
an der Empfangsseite.
Vielleicht eher daran, dass der Sender zu schwach ist, und nicht genug 
Buffer oder Leistung zur Verfügung stellt. Man sollte den Sender 
optimieren und dort mehr Leistung/Speicher zur Verfügung stellen.

von (prx) A. K. (prx)


Lesenswert?

PittyJ schrieb:
> Bei UDP können Pakete verloren gehen. Es gibt keinen Resend-Mechanismus.
> Den muss man selber schreiben.

Wenn - wie bei Messwerten oft der Fall - der aktuelle Wert wichtiger ist 
als die zwingend komplette Historie, dann ist TCP nicht nur nicht nötig, 
sondern geradezu schädlich. Entweder verzichtet man auf den Resend 
völlig, was bei einem sauberen lokalen Netz meist ausreicht, oder man 
baut nur einen Resend für den letzten Wert ein.

von Daniel A. (daniel-a)


Lesenswert?

Ich habe in der Vergangenheit schlechte Erfahrungen mit udp gemacht. 
Wenn ich mehrere GB an daten über um UDP versende, geht dass über main 
Lan problehmlos. Aber mein WLan verwirft dann 90% meiner Packete, so 
dass selbst mein Korrekturalgorythmus der diese erneut sendet ewigkeuten 
braucht, bis alles drüben ist ( manchmal Stunden!). War damals eine 
Chatanwendung die alles über Multicast versendete, damit ich sie nicht 
an jeden einzeln senden musste...

Sprich: Wenn man viel über UDP versendet können die Packete stauen und 
dan viele auf einmal verworfen werden.

von (prx) A. K. (prx)


Lesenswert?

Daniel A. schrieb:
> Ich habe in der Vergangenheit schlechte Erfahrungen mit udp gemacht.

Und ich habe schon Beispiele für kommerzielle Verwendung von TCP 
gesehen, in denen sich die Entwickler damit regelrecht ein Grab 
geschaufelt haben.

von Stefan F. (Gast)


Lesenswert?

> hast du Beispiel-Traces von Windows und Linux die das Verhalten
> zeigen?

Nein, sowas bewahre ich nicht auf.

von Forist (Gast)


Lesenswert?

Anderle K. schrieb:
> wird geACKed

> zu ACKen? Wie wären da die Fachausdrücke

Anderle K. schrieb:
> wenn der letzte frame geACKt wurde.

Du darfst hier im Forum ruhig das Verb "bestätigen" verwenden, auch wenn 
es in deinen Augen etwas unfachmännisch klingen mag.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.