aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/util/sock.cpp25
-rw-r--r--src/util/sock.h7
2 files changed, 32 insertions, 0 deletions
diff --git a/src/util/sock.cpp b/src/util/sock.cpp
index 36493ec241..e13c52a16a 100644
--- a/src/util/sock.cpp
+++ b/src/util/sock.cpp
@@ -250,6 +250,31 @@ std::string Sock::RecvUntilTerminator(uint8_t terminator,
}
}
+bool Sock::IsConnected(std::string& errmsg) const
+{
+ if (m_socket == INVALID_SOCKET) {
+ errmsg = "not connected";
+ return false;
+ }
+
+ char c;
+ switch (Recv(&c, sizeof(c), MSG_PEEK)) {
+ case -1: {
+ const int err = WSAGetLastError();
+ if (IOErrorIsPermanent(err)) {
+ errmsg = NetworkErrorString(err);
+ return false;
+ }
+ return true;
+ }
+ case 0:
+ errmsg = "closed";
+ return false;
+ default:
+ return true;
+ }
+}
+
#ifdef WIN32
std::string NetworkErrorString(int err)
{
diff --git a/src/util/sock.h b/src/util/sock.h
index 209d30def4..ecebb84205 100644
--- a/src/util/sock.h
+++ b/src/util/sock.h
@@ -143,6 +143,13 @@ public:
std::chrono::milliseconds timeout,
CThreadInterrupt& interrupt) const;
+ /**
+ * Check if still connected.
+ * @param[out] err The error string, if the socket has been disconnected.
+ * @return true if connected
+ */
+ virtual bool IsConnected(std::string& errmsg) const;
+
private:
/**
* Contained socket. `INVALID_SOCKET` designates the object is empty.