Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TcpClient connect fails with IPv6Any

Tags:

c#

ipv6

tcpclient

The problem is, the following code works well if IPAddress.Any was given as a parameter, but throws an error if `IPAddress.IPv6Any is used.

I receive error #10057

Socket is not connected.

A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using sendto) no address was supplied. Any other type of operation might also return this error—for example, setsockopt setting SO_KEEPALIVE if the connection has been reset.

Why does it fails to work as IPv6Any? I'm pretty sure it's not the firewall, since the port remains the same and it works with IPv4 (and my firewall should pass any requests made by my application).

To short up the code, it's something like this:

The Listener:

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

The Client:

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();
}

I'm trying to set up the "server-side" of the TCP-connection.

What I do is that I start a listener at localhost, and then connect to it as a client (and allow others to join as clients as well).

What I'm trying to achieve with this is direct addressability of this TCP server, following this article: http://blogs.msdn.com/b/ncl/archive/2009/07/27/end-to-end-connectivity-with-nat-traversal-.aspx

The reason I'm doing this is that I want person A to be able to connect to a person B when they both are behind NAT routers.

like image 627
Habba Avatar asked Nov 17 '11 17:11

Habba


2 Answers

I know this answer comes a bit late, but I also had this issue and it was client related. The problem is, that your provided code...

client = new TcpClient();

... creates an IPv4-Instance of the TcpClient that is not capable of interpreting IPv6-Addresses. So if you already have the IP address at the moment of initialization, try to initialize your TcpClient like this:

TcpClient client = new TcpClient(ip.AddressFamily);

If the variable ip is a string, you need to convert it to type IPAddress first:

IPAddress iAddr = IPAddress.Parse(ip);

Actually a IPv6-TcpClient seems to be compatible to IPv4-Addresses as well, so you can also initialize your client as follows:

TcpClient client = new TcpClient(AddressFamily.InterNetworkV6)

Whilst the upper suggestions seem to be the cleanest ones, the bottom suggestion seems to be the more universal one. At the end it's up to your preferences.

like image 168
CoastN Avatar answered Nov 12 '22 12:11

CoastN


I solved a similar issue where the following line would only block connections coming from IPv4 addresses:

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

It seems the socket when configured to accept IPv6 connections, by default, accepts ONLY IPv6 connections. To fix this problem i had to update my code to this:

listener.Server.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false);
listener.Start();
like image 36
Snellface Avatar answered Nov 12 '22 10:11

Snellface