2012-03-29 3 views
6

Ich verwende den Boost :: Asio, um eine Client/Server-Anwendung zu implementieren. Der folgende Clientcode wird zum Herstellen einer Verbindung mit dem Remoteserver verwendet.Wie überprüft man, ob eine Socket-Verbindung in Boost :: asio aktiv ist?

try 
    { 
     boost::asio::io_service   m_io_service; 
     boost::asio::ip::tcp::socket m_socket(m_io_service); 
     boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 17); 
     m_socket.connect(endpoint); 
    } 
    catch (std::exception& e) 
    { 
     std::cerr << e.what() << std::endl; 
    } 

Auf der Clientseite möchte ich überprüfen, ob die Verbindung aktiv ist. Die Funktion "m_socket.is_open();" funktioniert nicht. Wenn der Server-Socket geschlossen wird, gibt "m_socket.is_open();" auf Clientseite weiterhin True zurück. Gibt es eine Möglichkeit, die Verbindung zu überprüfen?

+1

Ich hatte einen ähnlichen Zweifel hier: http://Stackoverflow.com/q/1511129/174605 und es gibt eine feine Antwort von Joshperry – coelhudo

Antwort

2

Aufgrund der Einschränkungen der zugrundeliegenden Socket-Schnittstelle gibt es keine Möglichkeit, die Funktion wie isConnected zu implementieren, um den TCP-Verbindungsstatus auf Socket-Ebene zu überprüfen. Ich denke über einen Workaround nach.

In meiner Implementierung zwischenspeichern ich ein Verbindungsstatusflag (bool m_IsConnected) in meiner Anwendung. Dieses Flag wird verwendet, um den Verbindungsstatus zu bestimmen. Es wird davon ausgegangen, dass die TCP-Verbindung aktiv ist, wenn von Socket kein Fehler vorliegt.

Das Flag wird jedes Mal aktualisiert, wenn der Socket verwendet wird. Wenn beim Senden und Lesen von Daten Fehler auftreten, bedeutet dies, dass die Verbindung getrennt wurde. Dann ändere die Flagge entsprechend. Wenn die TCP-Verbindung längere Zeit inaktiv ist. Dieses Flag gibt den tatsächlichen Status der TCP-Verbindung erst wieder, wenn der Socket verwendet wird. Zum Beispiel ist der Socket für eine lange Zeit im Leerlauf. Es ist aufgrund des schlechten Netzwerkes getrennt. In diesem Fall ist m_IsConnected immer noch wahr, da wir keinen Rückruf bezüglich des Unterbrechungsereignisses erhalten. Wenn Sie versuchen, Daten über diesen Socket zu senden, wird ein Fehler angezeigt. Und jetzt wissen wir, dass die Verbindung getrennt ist.

0

Dies ist eine Einschränkung der zugrunde liegenden Socket-Schnittstelle (ich denke, sowohl für Winsock/Bekerly). Sie könnten eine Nachricht speziell für diesen Zweck erfinden, dass der Server antwortet, wenn er lebt. Andernfalls, wenn Sie eine Zeitüberschreitung erhalten, bedeutet dies, dass die Verbindung unterbrochen ist.

EDIT: Wie Joachim darauf hingewiesen, könnte der Versuch, den Sockel zu lesen, ein besserer Weg sein.

+3

Der Versuch, an eine Verbindung zu senden, die geschlossen wurde geben einen Fehler, auch wenn Es war ein sauberer und ordentlicher Abschluss. Der Versuch, _read_ vom Socket zu lesen, gibt einen besseren Hinweis darauf, wie der Socket geschlossen war (dh 'read' oder' recv' gibt Null für einen sauberen Abschluss oder einen Fehler zurück, wenn ein Fehler auftritt.) –

+0

Ach ja, du hast Recht, ich vergaß du könntest es auch lesen. Wird die obige Antwort aktualisieren. – Rolle

+0

Die freie Funktion boost :: asio :: read kann zum Lesen des Sockets verwendet werden. Ich denke, es gibt einen Nebeneffekt, wenn mit der Lesefunktion der Verbindungsstatus erkannt wird. Es liest die Daten aus dem Socket-Stream, die ich in einer Statuserkennungsfunktion nicht haben möchte. Wenn die Verbindung noch besteht, blockiert die Lesefunktion. – Jeffrey

Verwandte Themen