GNU/Linux >> LINUX-Kenntnisse >  >> Linux

So zerstören Sie eine Socket-Verbindung in C vollständig

Der close call markiert nur den TCP-Socket als geschlossen. Es kann nicht mehr vom Prozess verwendet werden. Der Kernel kann jedoch noch einige Ressourcen für einen bestimmten Zeitraum enthalten (TIME_WAIT, 2MLS usw.).

Das Setzen von SO_REUSEADDR sollte Bindungsprobleme beseitigen.

Stellen Sie also sicher, dass der Wert true ist beim Aufruf von setsockopt wirklich nicht null ist (Überlauffehler kann es überschreiben):

true = 1;
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&true,sizeof(int))

Es gibt pid Variable ist Ihr Code. Wenn Sie fork verwenden (zum Starten von Verbindungsbehandlungsprozessen), dann sollten Sie sock schließen auch im Prozess, der es nicht braucht.


Zuerst zur Benennung, damit wir dieselben Dinge alle gleich benennen:

Serverseitig:

Der Socket wurde an listen() übergeben und dann zu accept() nennen wir das Zuhören socket.Der von accept() zurückgegebene Socket nennen wir das akzeptiert Steckdose.

Clientseite:

Der Socket wurde an connect() übergeben nennen wir das connecting/connected Steckdose.

Zu Ihrem Problem:

Zum Beenden des accept() ed-Verbindung Schließen Sie akzeptiert Steckdose (was Sie verbunden nennen), indem Sie optional zuerst shutdown() verwenden gefolgt von close () .

Um dann eine neue Verbindungsschleife direkt vor dem Aufruf von accept() zu akzeptieren , nicht gehen Sie über bind() und listen() wieder.

Nur shutdown und Schließen Sie das Hören socket, wenn Sie pending loswerden möchten connect() s ausgestellt nach accept() zurückgegeben.


Die Verbindung ist noch aktiv, weil Sie vergessen haben, den verbundenen Socket zu schließen. Das Schließen der Abhörbuchse schließt nicht automatisch die verbundene Buchse.

//necessary code
close(connected);  // <---- add this line
close(sock);
goto label;

Ich bin mir jedoch nicht sicher, warum Sie EADDRINUSE bekommen. Der Code funktionierte sowohl unter Linux als auch unter Mac OS.


Linux
  1. So erhöhen Sie das Timeout der SSH-Verbindung

  2. Gewusst wie:Socket-Programmierung in Python

  3. Wie schließe ich die rmiregistry, die auf einem bestimmten Port ausgeführt wird?

  4. Wie entferne ich eine CLOSE_WAIT-Socket-Verbindung?

  5. Wie kann ich eine pconnect()-Verbindung schließen oder zurücksetzen, wenn ich PHPRedis und PHP-FPM verwende?

So zwingen Sie Wget, eine IPv4- oder IPv6-Verbindung zu verwenden

So binden Sie einen Raw-Socket an eine bestimmte Schnittstelle

Der Python-Socket schließt die Verbindung nicht ordnungsgemäß

Wie unterscheiden sich SO_REUSEADDR und SO_REUSEPORT?

Wie beende ich eine SSH-Verbindung?

So bestimmen Sie die Betriebszeit der Socket-Verbindung unter Linux