I am building an application that uses Windows sockets for communication. The Client
class handles the connection and spawns a thread that should periodically check if the connection is alive and if it's not, it should try to reconnect.
bool Client::Connect() {
fSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, nullptr, NULL, NULL);
if (WSAConnect(fSocket, (SOCKADDR*) &fAddress, sizeof(fAddress), nullptr, nullptr, nullptr, nullptr) != 0) {
return false;
}
return true;
}
void Client::StartConnectionAndKeepAlive() {
auto threadFunction = [this]() {
while (true) {
if (!this->fConnected) {
this->CloseConnection();
this->Connect();
this->Send("Hello from thread!\n");
}
this_thread::sleep_for(chrono::seconds(1));
}
};
fThread = new thread(threadFunction);
}
bool Client::Send(const string& data) {
auto nBytesSent = send(fSocket, data.c_str(), int(data.size()), NULL);
cout << "nBytesSent: " << nBytesSent << " for data: " << data << endl;
if (nBytesSent == SOCKET_ERROR) {
fConnected = false;
return false;
}
fConnected = true;
return true;
}
After instantiating Client
, Client::StartConnectionAndKeepAlive()
is called. If the connection is not possible, the value of send
will be equal to SOCKET_ERROR
as expected.
However my problem is when the server closes the connection (I am currently using netcat
and close the connection just by ctrl+C
). After closing the connection the return value of send
is the same as when the connection is alive. This causes the flag fConnected
to stay true and therefor the connection won't be restablished even if I launch netcat
again.
This is the first time I am working with sockets and windows so I am surely mising something but I couldn't find a solution online. All similar question responses state that the return value of send
should be SOCKET_ERROR
if there is no connection (if I understood them correctly) but I found it's not the case.
I am aware that I should probably use std::mutex
in my class since I am using it from multiple threads but found that adding it doesn't make my problem disappear, I removed them to keep the code simpler.
Any feedback to my implementation is also welcome! Thanks!