当我连接到远程服务器时,我试图为我的应用程序找到一种通过 TCP 检测断开连接的方法。我在想最明显的方法是使用 TCP keepalive 选项。这是一个 MFC C++ 应用程序,MySock 类继承自 CSocket。我曾尝试在调用 Connect 之前和之后设置 SO_KEEPALIVE 选项,但我从未见过通过wireshark 发送keepalive 数据包。我可以看到我在连接上发送的所有数据都很好,所以我知道它已经连接并且正在工作。
if (!(m_connection = new MySock(this)))
{
AfxMessageBox ("Failed to allocate socket! Close and restart app.");
m_connect.EnableWindow(true);
return false;
}
if (!m_connection->Create())
{
AfxMessageBox ("Failed to create client socket! Close and restart app.");
m_connect.EnableWindow(true);
return false;
}
TCHAR buff[128];
DWORD optval = true;
int temp = sizeof(DWORD);
if (!m_connection->GetSockOpt(SO_KEEPALIVE, (void*)&optval, &temp, SOL_SOCKET))
{
wsprintf (buff, "GetSockOpt Error %d", GetLastError());
AfxMessageBox (buff);
}
wsprintf (buff, "GetSockOpt %d", optval);
AfxMessageBox (buff);
optval = true;
temp = sizeof(DWORD);
if (!m_connection->SetSockOpt(SO_KEEPALIVE, (void*)&optval, temp, SOL_SOCKET))
{
wsprintf (buff, "SetSockOpt Error %d", GetLastError());
AfxMessageBox (buff);
}
optval = false;
temp = sizeof(DWORD);
if (!m_connection->GetSockOpt(SO_KEEPALIVE, (void*)&optval, &temp, SOL_SOCKET))
{
wsprintf (buff, "GetSockOpt Error %d", GetLastError());
AfxMessageBox (buff);
}
wsprintf (buff, "GetSockOpt %d", optval);
AfxMessageBox (buff);
CString consoleText;
m_console.GetWindowText(consoleText);
consoleText += "Control Connected!\r\n";
m_console.SetWindowText(consoleText);
if (!m_connection->Connect(address, CONTROL_PORT))
{
AfxMessageBox ("Failed to connect");
m_connection->Close();
delete m_connection;
m_connection = NULL;
m_connect.EnableWindow(true);
return false;
}
optval = false;
temp = sizeof(DWORD);
if (!m_xcmp->GetSockOpt(SO_KEEPALIVE, (void*)&optval, &temp, SOL_SOCKET))
{
wsprintf (buff, "GetSockOpt Error %d", GetLastError());
AfxMessageBox (buff);
}
wsprintf (buff, "GetSockOpt %d", optval);
AfxMessageBox (buff);
在调用 SetSockOpt 之前调用 GetSockOpt 时 optval 的值为 0,调用之后为 1。连接后的值仍设置为 1。我在调用 GetSockOpt 之前将 optval 设置为 0,以确保没有发生任何奇怪的事情。Get 或 Set 都没有返回错误。任何帮助或想法将不胜感激。我目前的理论是客户端连接(我正在连接到侦听套接字)不发送保活。keepalives 是否仅来自作为侦听器的连接?谢谢你的时间。