.net 如何检查TCP连接是否关闭,考虑IPV6?

1wnzp6jl  于 2023-07-01  发布在  .NET
关注(0)|答案(2)|浏览(133)

我使用this code来检查TCP连接是否关闭。然而,在使用这段代码时,我注意到如果连接使用的是IPV4,则它不适用于IPV6地址:

if (!socket.Connected) return false;

        var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
        var tcpConnections = ipProperties.GetActiveTcpConnections()
            .Where(x => x.LocalEndPoint.Equals(socket.LocalEndPoint) && x.RemoteEndPoint.Equals(socket.RemoteEndPoint));

        var isConnected = false;

        if (tcpConnections != null && tcpConnections.Any())
        {
            TcpState stateOfConnection = tcpConnections.First().State;
            if (stateOfConnection == TcpState.Established)
            {
                isConnected = true;
            }
        }

        return isConnected;

在调试链接答案中的代码时,我注意到返回了一个包含以下端点的列表:
[2019 - 05 - 15]
然而,我正在测试的套接字似乎是IPV6:
[2019 - 05 - 15] 01:05:00
{127.0.0.1:50503} == {[::ffff:127.0.0.1]:50503}返回false,因此检查失败。
如何测试IPV4地址和IPV6地址是否指向同一主机?

vktxenjb

vktxenjb1#

我最终创建了一个检查,如果另一端是IPV6,则将端点“提升”到IPV6:

public static bool IsConnectionEstablished(this Socket socket)
{
    if (socket is null)
    {
        throw new ArgumentNullException(nameof(socket));
    }

    if (!socket.Connected) return false;

    var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
    var tcpConnections = ipProperties.GetActiveTcpConnections()
        .Where(x => x.LocalEndPoint is IPEndPoint && x.RemoteEndPoint is IPEndPoint && x.LocalEndPoint != null && x.RemoteEndPoint != null)
        .Where(x => AreEndpointsEqual(x.LocalEndPoint, (IPEndPoint)socket.LocalEndPoint!) && AreEndpointsEqual(x.RemoteEndPoint, (IPEndPoint)socket.RemoteEndPoint!));

    var isConnected = false;

    if (tcpConnections != null && tcpConnections.Any())
    {
        TcpState stateOfConnection = tcpConnections.First().State;
        if (stateOfConnection == TcpState.Established)
        {
            isConnected = true;
        }
    }

    return isConnected;
}

public static bool AreEndpointsEqual(IPEndPoint left, IPEndPoint right)
{
    if (left.AddressFamily == AddressFamily.InterNetwork &&
        right.AddressFamily == AddressFamily.InterNetworkV6)
    {
        left = new IPEndPoint(left.Address.MapToIPv6(), left.Port);
    }

    if (left.AddressFamily == AddressFamily.InterNetworkV6 &&
        right.AddressFamily == AddressFamily.InterNetwork)
    {
        right = new IPEndPoint(right.Address.MapToIPv6(), right.Port);
    }

    return left.Equals(right);
}
gmol1639

gmol16392#

在创建TCP客户端套接字时,可以向构造函数传递一个参数以显式使用ipv4地址

new TcpClient(AddressFamily.InterNetwork);

相关问题