I encountered a strange error with TCP sockets. It seems to be SO_KEEPALIVEenabled by default on all sockets.
I wrote a short test case for creating a socket and connecting to a server. Immediately after connecting, I check SO_KEEPALIVEfor getsockopt. A value other than zero, which, according to MSDN, means that support is supported. Perhaps I do not understand this.
I recently had a strange error when the server shutdown twice in a row. Some clients were in a state where they were sending login information and waiting for a response. Although a “t23” was imposed on the socket connected to the server, a termination was not sent to notify the client of the server failure, so I assume that the socket was not completely closed.
After about 2 hours (actually about 1 hour, 59 minutes and 19 seconds), a completion packet was sent to read, notifying the client that the connection was no longer open. Here I began to suspect SO_KEEPALIVE.
I am trying to understand why this happened. This caused some problems, because clients that lost connection for any reason should automatically connect to the server; in this case, since the disconnect notification was not notified, the client did not connect until 2 hours later.
An explicit fix is to set a timeout, but I would like to know how this situation could happen.
SO_KEEPALIVE not installed on the socket by my application server or client.
int main() {
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
SOCKET foo = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, 0);
DWORD optval;
int optlen = sizeof(optval);
int test = 0;
test = getsockopt(foo, SOL_SOCKET, SO_KEEPALIVE, (char*)&optval, &optlen);
std::cout << "Returned " << optval << std::endl;
sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr("127.0.0.1");
clientService.sin_port = htons(446);
connect(foo, (SOCKADDR*) &clientService, sizeof(clientService));
test = getsockopt(foo, SOL_SOCKET, SO_KEEPALIVE, (char*)&optval, &optlen);
std::cout << "Returned " << optval << std::endl;
std::cin.get();
return 0;
}