Forum: PC-Programmierung [C] TCP Client Problem Linux


von Stored B. (Firma: drx) (umbrecht)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe einen ESP8266 als Server und einen Client am Linux oder Windows 
PC. U.U. kann es sein das die Verbindung verloren geht und ich möchte 
einen "erneuten" Verbindungsaufbau versuchen. Auf Windows funktioniert 
das ganze super. Nur auf Linux habe ich das Problem dass das Programm 
abstürzt sobald connection_status gesetzt ist.

Weiß jemand von euch warum? Habe einen Server für Windows testweise 
erstellt. Dieser ersetzt den ESP. Ich hänge beide Dateien an.

Vielen dank für eure Hilfe.

mfg
Umbrecht

von Εrnst B. (ernst)


Lesenswert?

Dein Server akzeptiert nur einmal eine Verbindung, und keine weitere.

das accept
1
fd = accept(sock, (struct sockaddr*)&client, &len);
muss mit in eine Schleife.

von Stored B. (Firma: drx) (umbrecht)


Lesenswert?

Danke für deine Antwort, ich versuche es gleich. Aber warum funktioniert 
der Client unter Windows? Er kann sich beliebig oft wieder verbinden, 
der Server ist hierbei aber der gleiche.

von Εrnst B. (ernst)


Lesenswert?

Stored B. schrieb:
> Er kann sich beliebig oft wieder verbinden,
> der Server ist hierbei aber der gleiche.

die server_mc.c? Kann nicht sein. Darin wird nur einmal "accept" 
ausgeführt, deshalb kann dieser Server auch nur eine TCP-Verbindung 
bearbeiten.

(rein "entgegennehmen" kann er 5 (parameter zu listen), aber auf den 
anderen sendet/empfängt er nix)

von Stored B. (Firma: drx) (umbrecht)


Lesenswert?

Εrnst B. schrieb:
> die server_mc.c? Kann nicht sein. Darin wird nur einmal "accept"
> ausgeführt, deshalb kann dieser Server auch nur eine TCP-Verbindung
> bearbeiten.
>
> (rein "entgegennehmen" kann er 5 (parameter zu listen), aber auf den
> anderen sendet/empfängt er nix)

Das stimmt natürlich, ich habe mich schlecht ausgedrückt, ich Simuliere 
einen Verbindungsabbruch durch beenden des Servers und erneuten Starten 
des Servers. Der Client auf Windows verbindet sich dann wieder. Der 
Client auf Linux beendet sich sofort nachdem der Server beendet wird, 
hier komme ich gar nicht dazu den Verbindungsaufbau erneut zu testen.

von Εrnst B. (ernst)


Lesenswert?

Stored B. schrieb:
> Der
> Client auf Linux beendet sich sofort nachdem der Server beendet wird,

Dann zeig doch mal die Ausgaben vom Programm, wenn das passiert.
Sind ja einige Debug-Prints vorhanden.

Der Fehler ist tatsächlich etwas fies zu finden, lustigerweise passiert 
er schon bevor "connection_status" umgestellt wird.

: Bearbeitet durch User
von Stored B. (Firma: drx) (umbrecht)


Lesenswert?

Heute komme ich leider an keinen PC mehr, schicke morgen mal Screenshots 
von der Konsole. Viel sieht man aber nicht, außer das typische Konsolen 
eingabefeld, es kommt keine Fehlermeldung.

Dann muss der Auslöser eigentlich send oder recv sein. Habe ich 
vielleicht etwas falsch konfiguriert?

von Εrnst B. (ernst)


Lesenswert?

Stored B. schrieb:
> Dann muss der Auslöser eigentlich send oder recv sein.
Ja.

Beim send auf einen toten Socket kriegt dein Program ein SIGPIPE und der 
send-Rückgabewert ist EPIPE. Rückgabewert prüfst du, aber nachdem das 
SIGPIPE von dir weder behandelt noch weg-ignoriert wird, beendet sich 
das Programm.

d.H. zwei Lösungsvorschläge:

"send" mit flag 'MSG_NOSIGNAL' aufrufen, also:
1
if (send(sock, &rec, 1, MSG_NOSIGNAL) < 0) {

oder

SIGPIPE ignorieren:
1
signal(SIGPIPE, SIG_IGN);

von Stored B. (Firma: drx) (umbrecht)


Lesenswert?

Εrnst B. schrieb:

> "send" mit flag 'MSG_NOSIGNAL' aufrufen, also:
>
1
if (send(sock, &rec, 1, MSG_NOSIGNAL) < 0) {


Guten morgen,

mit diesem Lösungsvorschlag funktioniert es. Vielen dank!

mfg
Umbrecht

von Horst (Gast)


Lesenswert?

Ich muss sagen dass ich dieses Problem nicht kenne und noch nie den 
Signalhandler SIGPIPE umgeleitet habe.

Jedoch frage ich über "select" stets zuerst ob ich den Socket lesen 
kann. Dies wird signalisiert und beim lesen des Sockets bekomme ich den 
Fehler, dass der Socket geschlossen wurde und kann darauf reagieren (den 
Socket ebenfalls schließen und nicht weiter verwenden). So bin ich stets 
ans Ziel gekommen ohne diesen Fehler je zu Gesicht zu bekommen.

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.