TcpClient连接失败,IPv6Any

时间:2011-11-17 17:56:56

标签: c# ipv6 tcpclient

问题是,如果IPAddress.Any作为参数给出,则以下代码可以正常工作,但如果使用`IPAddress.IPv6Any则抛出错误。

我收到错误#10057

  

套接字未连接。

     

由于套接字是,因此不允许发送或接收数据的请求   未连接和(使用时在数据报套接字上发送)   sendto)没有提供地址。任何其他类型的操作都可能   也返回此错误 - 例如,setsockopt设置SO_KEEPALIVE if   连接已重置。

为什么它不能像IPv6一样工作?我很确定它不是防火墙,因为端口保持不变并且它与IPv4一起使用(我的防火墙应该传递我的应用程序发出的任何请求)。

为了简化代码,它是这样的:

听众:

listener = new TcpListener(IPAddress.IPv6Any, portNr);
listener.AllowNatTraversal(true);
listener.Start();
listener.BeginAcceptTcpClient(this.AcceptClient, null);

客户:

client = new TcpClient();
client.NoDelay = true;            

try
{
    this.client.Connect(ip, port);  //ip = "localhost" when connecting as server
}
catch (Exception ex)
{
    FileLogger.LogMessage(ex);
    Disconnect();
}

我正在尝试设置TCP连接的“服务器端”。

我所做的是在localhost启动一个监听器,然后作为客户端连接到它(并允许其他人作为客户端加入)。

我想要实现的是这个TCP服务器的直接可寻址性,遵循这篇文章:http://blogs.msdn.com/b/ncl/archive/2009/07/27/end-to-end-connectivity-with-nat-traversal-.aspx

我这样做的原因是我希望A人能够在他们都在NAT路由器后面时连接到B人。

4 个答案:

答案 0 :(得分:1)

我解决了类似的问题,其中以下行只会阻止来自IPv4地址的连接:

listener = new TcpListener(IPAddress.IPv6Any, portNr);

默认情况下,配置为接受IPv6连接时,套接字似乎只接受IPv6连接。要解决此问题,我必须将我的代码更新为:

listener.Server.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false);
listener.Start();

答案 1 :(得分:1)

我知道这个答案有点迟了,但我也有这个问题,而且与客户有关。问题是,你提供的代码......

client = new TcpClient();

...创建TcpClient的IPv4实例,该实例无法解释IPv6地址。因此,如果您在初始化时已经拥有IP地址,请尝试初始化您的TcpClient,如下所示:

TcpClient client = new TcpClient(ip.AddressFamily);

如果变量ip是一个字符串,则需要先将其转换为IPAddress类型:

IPAddress iAddr = IPAddress.Parse(ip);

实际上IPv6-TcpClient似乎也与IPv4地址兼容,因此您也可以按如下方式初始化您的客户端:

TcpClient client = new TcpClient(AddressFamily.InterNetworkV6)

虽然上层建议似乎是最干净的建议,但最底层的建议似乎是更普遍的建议。最后,这取决于您的偏好。

答案 2 :(得分:0)

IPAddress.Loopback == FAIL
IPAddress.IPv6Loopback == SUCCESS

或许localhost映射到您的IPv4 Loopback地址?

答案 3 :(得分:0)

当您使用TcpClient.Connect(string, int)时,您可以因DNS解析而中断。

虽然Microsoft会首先尝试使用IPv6地址,但分辨率可能只返回IPv4地址。

http://msdn.microsoft.com/en-us/library/8s2yca91.aspx

因此,您是否可以尝试在客户端调用TcpClient.Connect(IPAddress.IPv6Loopback, port)来测试它是否有效?