【问题标题】:MFC CSocket keepalive packets not sendingMFC CSocket keepalive数据包未发送
【发布时间】:2011-10-20 21:22:10
【问题描述】:

我正在尝试为我的应用程序找到一种方法,以便在我连接到远程服务器时通过 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 是否仅来自作为侦听器的连接?感谢您的宝贵时间。

【问题讨论】:

    标签: sockets visual-c++ mfc mfc-networking


    【解决方案1】:

    默认的 TCP 保持活动超时为 7200 秒,即 两个小时,因此您必须等待很长时间才能看到其中的任何一个。这个超时通常在 Unix 上用sysctl(8) 控制,Windows 可能在KEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters 下有一些注册表项,我不知道。这是一个简短的overview of the TCP KeepAlive mechanism。

    我还要注意,这并不是非常有用。你最好在你的应用协议中实现某种心跳机制,不仅可以检测断开连接,还可以检测滞后和卡住的对等点。

    【讨论】:

    • 非常感谢您成功了。仔细检查后,该功能确实不是我想要的。当然,我在工作了几天后在这里询问后几分钟就发现了这个问题,LOL 总是会发生。我在想这就像每隔几秒的 ping 机制,但这不是它的用途。
    【解决方案2】:

    setsockopt() 只能启用/禁用“keep-alive”选项,默认 TCP keep-alive 超时为 7200 秒。 看看 WSAIoctl() | SIO_KEEPALIVE_VALS,它也可以改变keep-alive超时和间隔。

    【讨论】:

      猜你喜欢
      • 2012-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-27
      相关资源
      最近更新 更多