I have win32 application in which winsock is used for TCP/IP communication. I am setting keepalive value with WSAIoctl function and it is working normally with windows XP.
But on Win. Server 2008 WSAIoctl fails, and WSAGetLastError returns 10022(invalid arguments) which does not make any sense.
My code which sets keepalive is follows;
// set per-connection keep-alive o开发者_如何学编程ption
tcp_keepalive keepAliveSettings;
keepAliveSettings.onoff = 1;
keepAliveSettings.keepalivetime = 500;
eepAliveSettings.keepaliveinterval = 25;
int lastError = WSAIoctl(m_soc.chns[0], SIO_KEEPALIVE_VALS, &keepAliveSettings, sizeof(keepAliveSettings), NULL, 0, &BytesReturned, NULL, NULL);
if(lastError == SOCKET_ERROR) {
lastError = WSAGetLastError();
Logger::Error("Setting keepalive failed ErrCode %d\n",lastError); }
EDIT:
I found the solution, maybe it can help someone else who faced same problem. I was trying to set keepalive just after the async. connect call, but now I am setting after completion of connect call and this solved the issue.
From http://msdn.microsoft.com/en-us/library/ee470551(v=VS.85).aspx
On Windows Vista and later, the SO_KEEPALIVE socket option can only be set using the setsockopt function when the socket is in a well-known state not a transitional state. For TCP, the SO_KEEPALIVE socket option should be set either before the connect function (connect, ConnectEx, WSAConnect, WSAConnectByList, or WSAConnectByName) is called, or after the connection request is actually completed. If the connect function was called asynchronously, then this requires waiting for the connection completion before trying to set the SO_KEEPALIVE socket option. If an application attempts to set the SO_KEEPALIVE socket option when a connection request is still in process, the setsockopt function will fail and return WSAEINVAL.
I found the solution, maybe it can help someone else who faced same problem. I was trying to set keepalive just after the async. connect call, but now I am setting after completion of connect call and this solved the issue.
From http://msdn.microsoft.com/en-us/library/ee470551(v=VS.85).aspx
On Windows Vista and later, the SO_KEEPALIVE socket option can only be set using the setsockopt function when the socket is in a well-known state not a transitional state. For TCP, the SO_KEEPALIVE socket option should be set either before the connect function (connect, ConnectEx, WSAConnect, WSAConnectByList, or WSAConnectByName) is called, or after the connection request is actually completed. If the connect function was called asynchronously, then this requires waiting for the connection completion before trying to set the SO_KEEPALIVE socket option. If an application attempts to set the SO_KEEPALIVE socket option when a connection request is still in process, the setsockopt function will fail and return WSAEINVAL.
Probably the kernel is objecting to your choices of values. I would. You can't seriously want to set the keep-alive interval to 25ms. That is a completely insane value. The default value is two hours, and there is no point in setting it lower than several minutes. Similarly the keepalivetime should be set to half an hour or so, certainly not half a second.
精彩评论