Haengende TCP-Verbindungen

04/07/2008 - 15:48 von Till Wollenberg | Report spam
Hallo!

Ich habe hier ein Problem mit einem kleinen C-Programm, dass auf Embedded-Systemen
laufen soll. Es nimmt Messdaten auf und schickt diese in regelmàßigen Abstànden via
HTTP an einen Mess-Server. Die Anbindung geht über WLAN und leidet tlw. unter sehr
hohen Paketverlusten.

Sporadisch tritt jetzt das Problem auf, dass die TCP-Verbindung (HTTP) "hàngen bleibt":
es gehen keinerlei Pakete in die eine oder andere Richtung (mit tcpdump getestet) und
read() oder write() blockieren unendlich lang. Der Fehler trat bisher sowohl unter
Linux 2.6.23.17 (mips) als auch unter Linux 2.4.30 (mipsel) auf.

netstat sagt in diesem Zustand:

| Active Internet connections (w/o servers)
| Proto Recv-Q Send-Q Local Address Foreign Address State
| tcp 0 0 192.168.1.200:46270 xxx.yyy.zzz.zzz:80 ESTABLISHED

In diesem Fall hàngt die Verbindung schon 80 Minuten. Sollte TCP-Keepalive sowas nicht verhindern?

# sysctl -a | grep keepalive
net.ipv4.tcp_keepalive_time = 120
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_intvl = 75

Wenn ich das richtig verstanden habe, wird alle 120 Sekunden ein Keepalive gesendet.
Auf eine Antwort wird dabei 75 Sekunden gewartet. Wenn 9 Versuche fehlschlagen, wird
die Verbindung beendet.

Warum springt das bei mir nicht an?

Für HTTP benutze ich die Bibliothek "HTTP Tiny" [1]. Der Code sieht etwa so aus:

| [...]
| /* create socket */
| if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
| return ERRSOCK;
| setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, 0, 0);
|
| /* connect to server */
| if (connect(s, (struct sockaddr*)&server, sizeof(server)) < 0)
|
| [...]
|
| /* send header */
| if (write(s,header,hlg)!=hlg)
| ret= ERRWRHD;


Gruß, Till.


[1] http://www.demailly.com/~dl/http-tiny-1.2.tar.gz

wollenberg (at) web (punkt) de
 

Lesen sie die antworten

#1 Oliver Schneidewind
07/07/2008 - 07:59 | Warnen spam
Hallo,

Till Wollenberg schrieb:
Hallo!

Ich habe hier ein Problem mit einem kleinen C-Programm, dass auf
Embedded-Systemen
laufen soll. Es nimmt Messdaten auf und schickt diese in regelmàßigen
Abstànden via
HTTP an einen Mess-Server. Die Anbindung geht über WLAN und leidet tlw.
unter sehr
hohen Paketverlusten.



Ja ja das WLAN, ein Kabel hat ein Anfang und ein Ende, bei WLAN ist
man sich da nie sicher.

Sporadisch tritt jetzt das Problem auf, dass die TCP-Verbindung (HTTP)
"hàngen bleibt":
es gehen keinerlei Pakete in die eine oder andere Richtung (mit tcpdump
getestet)



nur zur sicherheit auf einen der Beiden beteilligten MAschien oder mit
einer Dritten?

read() oder write() blockieren unendlich lang. Der Fehler trat bisher
sowohl unter
Linux 2.6.23.17 (mips) als auch unter Linux 2.4.30 (mipsel) auf.



da wie du sagst, das Embedded System regelmàssig mess Daten schick warum
umgibst du dein Read/Write nicht mit Select und definierst ein Timeout?
So bekommt dein Programm mit wenn es mal wieder nichts ankommt wie du
sagst.

netstat sagt in diesem Zustand:

| Active Internet connections (w/o servers)
| Proto Recv-Q Send-Q Local Address Foreign Address State
| tcp 0 0 192.168.1.200:46270 xxx.yyy.zzz.zzz:80
ESTABLISHED



das sieht normal aus. Verbindung besteht.

In diesem Fall hàngt die Verbindung schon 80 Minuten. Sollte
TCP-Keepalive sowas nicht verhindern?



jupp. Kann es sein das dein Embedded System in ein Deadlock stolpert
und deshalb keine Daten mehr gesendet werden. Ich hatte mal ein Fall wo
ein Memory Leak dafür gesort hat das irgendwann der TCP/Stack kein
Speicher für sein Daten allocieren könnte und daher nicht mehr gesendet
hat.

Oliver

Ähnliche fragen