TCP socket: send() wird erfolgreich ausgeführt, die Daten aber erst später gesendet...
-
Hallo Forum,
ich habe ein Problem beim Senden von Daten. Der Linux-Rechner bekommt alle 50ms eine Nachricht über ein TCP/IP Socket, auf die er möglichst bald darauf antworten soll, was auch in der Regel erfolgreich funktioniert.
In der Regel heisst aber: nicht immer! Von Zeit zu Zeit werden keine Daten versendet. Obwohl - wie immer - send() erfolgreich ausgeführt wird. Erst nach 250~ms werden die Daten tatsächlich auf die Leitung gelegt. Manchmal erscheint bei diesem Vorfall die Fehlermeldung:eth0: transmit buffer not free!
oder
NETDEV WATCHDOG: etho: transmit timed out
Kann es sein, dass 50ms zu schnell ist? Die gleiche Übertragung (ebenfalls alle 50ms) funktioniert wunderbar über die serielle Verbindung (RS-232).
Viele Grüße,
yecc
-
Das kann sowohl an der Bufferung im Kernel, als auch an dem Treiber der Netzwerkkarte liegen. Probier vielleicht mal eine andere Netzwerkkarte (mit anderem Treiber und Chipsatz) aus, wenn möglich. Ansonsten schau mal ob du mit ioctl oder fcntl auf die Bufferung im Kernel einfluss nehmen kannst.
-
Hallo und Danke für die Antwort,
ich habe mit den beiden Funktionen alles mögliche angestellt, aber es hilft nichts. Habe sogar mit select() geprüft, ob der Port sendebereit ist oder geprüft, ob send() einen Fehler zurückgibt....
was aber die Situation verbessert hat: Ich habe das System direkt vor dem send()-Befehl mit nanosleep() ca 50µs schlafen gelegt. Der Fehler tritt jetzt seltener auf, kommt aber immer noch ab und zu vor. Vielleicht hilft das jemand, mich auf die "ideale" Lösung zu bringen...
Vielen Dank und Gruß,
yecc
-
Wenn etwas "so schnell" wie möglich senden soll, ist TCP nicht unbedingt die beste der Möglichkeiten ... UDP wäre hier sinnvoller
Bei TCP kann es dir wegen der Flusskontrolle mal immer vorkommen, dass der Sendepuffer voll ist. Ich schätze, auch andere Anwendungen können dir hier Platz nehmen.
-
Es gibt eine Socket Option SO_NODELAY oder so ähnlich. Google nach "Nagle algorithm", dann findest du's sicher.
-
Hallo und Danke,
SO_NODELAY ist bereits aktiviert....kann es sein, daß es am Kernel liegt oder an der Netzwerkkarte? Oder am TCP/IP selbst? Das Problem tritt bei Kernel 2.4 und 2.6 auf. Hab auch schon versch. Netzwerkkarten getetstet... immer das gleiche. Mit dem Tool "Ethereal" habe ich auch schon den Netzwerkverkehr protokolliert:
Mit der Ausführung von send() wird ein Segment FORMAL losgeschickt, das aber nicht auf die Leitung gelegt wird. Erst 250~ms später erfolgt eine TCP Retransmission. Dann wird das Segment erst physikalisch übertragen. Kann mir jemand sagen, warum das Segement nicht beim ersten Mal gesendet werden konnte?Danke und Gruß
-
Haben die TCP-Pakete denn das Push-Bit gesetzt?
-
Was ist das? bzw. wie aktiviert / deaktiviert man das?
-
Ist ein Flag von einem TCP-Paket. Man kann es im Ethereal schön sehen (durch "P" glaube ich). Sollte gesetzt sein, wenn SO_NODELAY aktiv ist.
-
Jo, das Bit ist bei jeder Übertragung gesetzt...
das Problem besteh weiterhin
-
Hmm, das schaut mir aber jetzt auf den zweiten Blick doch eher wie ein Hardware-/Treiberproblem aus. Nimm wirklich mal eine andere Netzwerkkarte.
-
Hm... das kann erst noch sein... Bei zwei PC's mit 3Com-Netzwerkkarte trat der Fehler nicht auf, jedoch bei einem Notebook mit einer Netzwerkkarte, die mit einem VIA-Chipsatz bestückt ist... (gehören VIA-Netzwerkkarten eher zu den billigeren????)
neben 3Com sollen auch Netzwerkkarten von Intel gut sein und welche mit Realtek-Chipsatz vergleichsweise schlecht... gibt es noch weitere Firmen? Wie sind diese einzuordnen?
Gruß, yecc
-
Realtek sind super!
Sie haben zwar keine solch CPU-entlastenden Mechanismen wie die von Intel oder von 3com, aber ich habe seit Jahren etliche im Einsatz, und die funktionieren alle absolut problemlos.
VIA hingegen ist Schrott, in jeder nur erdenklichen Form.