【问题标题】:Determining if .NET socket is currently connected bug?确定 .NET 套接字当前是否已连接错误?
【发布时间】:2009-09-09 18:08:32
【问题描述】:

我正在尝试找出当前是否连接了 Socket - 根据 Socket.Connected 的 MSDN 文档 - 我应该执行以下操作:

// This is how you can determine whether a socket is still connected.
bool blockingState = client.Blocking;
try
{
    byte [] tmp = new byte[1];

    client.Blocking = false;
    client.Send(tmp, 0, 0);
    Console.WriteLine("Connected!");
}
catch (SocketException e) 
{
    // 10035 == WSAEWOULDBLOCK
    if (e.NativeErrorCode.Equals(10035))
        Console.WriteLine("Still Connected, but the Send would block");
    else
    {
        Console.WriteLine("Disconnected: error code {0}!", e.NativeErrorCode);
    }
}
finally
{
    client.Blocking = blockingState;
}

 Console.WriteLine("Connected: {0}", client.Connected);

我已经通过将套接字连接到在 Windows 上运行的远程服务器并终止远程服务器来测试它是否可以正常工作。

但是,如果我对运行在 Unix 上的远程服务器(在本例中为 MAC OS X)执行相同操作,则代码不起作用 - client.Send(tmp, 0, 0) 调用完成而不会引发异常并打印“已连接:true”。

我猜这与连接的另一端已关闭的事实有关,因此发送可能仍然有效,但接收会失败 - 我可以做一个零字节接收或其他什么来看看套接字已关闭?

【问题讨论】:

    标签: c# windows linux tcp


    【解决方案1】:

    是的,你可以。

    调用 Send 只真正检查本地套接字是否打开。调用 Receive 也会检查另一端。

    【讨论】:

    • 当我在远程对等方断开连接后使用 Receive 时,它​​也成功完成但返回 0 - 这是检测连接丢失的可靠方法吗?
    • 不幸的是,实际上并没有一种故障安全方法来检测连接是否仍然存在,而无需实际尝试使用连接并捕获任何错误/异常。将您的套接字连接包装在一个带有接收缓冲区的类中是非常标准的,这样您就可以从线路中读取实际数据以测试连接并将其存储起来以供以后真正想要使用它时使用。此外,正如 Oliver 所说,TCP 堆栈的各种实现之间存在差异,这意味着您将从不同的对等方获得不同的行为。
    【解决方案2】:

    也许你可以用 Wireshark 嗅探流量,看看垂死的服务器端是 windows 还是 unix 系统是否有任何区别。

    也许垂死的 windows 系统能够发送一个 tcp 关闭,而 unix 系统不能。这可以解释差异(但可能对您的实际问题没有帮助)。

    顺便说一句,如果您使用 udp 连接,您将永远无法确定其他站点是否存在,因为这将是发送后忘记通信。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-05
      • 2012-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-31
      相关资源
      最近更新 更多