Search Unity

IPv6: TcpClient.BeginConnect doesn't work

Discussion in 'Scripting' started by Asse1, Jun 22, 2016.

  1. Asse1

    Asse1

    Joined:
    Jan 9, 2013
    Posts:
    89
    We're currently fixing the iOS IPv6 issues and therefor have also upgraded to Unity 5.3.5p4.

    Now first things first, with a standard connection everything works perfectly fine. But when it comes to testing IPv6 with a NAT-64 wifi network shared by our mac I have the following problem (happens in editor and on iOS device with IL2CPP).

    We do synchronous networking calls (blocking) with the following code:

    Code (CSharp):
    1. var ipAddresses = DnsUtils.ResolveName(this.Uri.Host, this.SendTimeout);
    2.  
    3. using (this.client = new TcpClient())
    4. {
    5.         this.client.SendTimeout = this.SendTimeout;
    6.         this.client.ReceiveTimeout = this.ReceiveTimeout;
    7.         this.client.Connect(ipAddresses, this.Uri.Port);
    8.         return this.GetResponseFromStream();
    9. }
    This code works fine.

    Now we also have asynchronous calls (non-blocking) with the following code:

    Code (CSharp):
    1. var ipAddresses = DnsUtils.ResolveName(req.Uri.Host, req.SendTimeout);
    2.  
    3. req.client = new TcpClient();
    4. req.client.SendTimeout = req.SendTimeout;
    5. req.client.ReceiveTimeout = req.ReceiveTimeout;
    6. req.client.BeginConnect(ipAddresses, req.Uri.Port, req.ExecuteRequestCallback, executeState);
    And this code responds with the following error,
    I don't think that we're using anything wrong since this code works for several years now. The resolved ip addresses are correct by the way.

    Did anybody encounter the same problem and found a solution? Or is this problem maybe already known to the Unity development team?
     
    Last edited: Jun 23, 2016
  2. Asse1

    Asse1

    Joined:
    Jan 9, 2013
    Posts:
    89
    Ok, when I initialize the TcpClient with AddressFamily.InterNetworkV6 then everything works fine (which isn't needed in the synchronous version)

    Code (CSharp):
    1. var ipAddresses = DnsUtils.ResolveName(req.Uri.Host, req.SendTimeout);
    2.  
    3. req.client = new TcpClient(AddressFamily.InterNetworkV6);
    4. req.client.SendTimeout = req.SendTimeout;
    5. req.client.ReceiveTimeout = req.ReceiveTimeout;
    6. req.client.BeginConnect(ipAddresses, req.Uri.Port, req.ExecuteRequestCallback, executeState);
    Now the thing is, that I have an array of ip addresses, some are IPv4 and some are IPv6.

    Is it so that one isn't allowed to pass addresses of different families to the BeginConnect but you have to know beforehand what kind of family you want to support?
     
  3. Asse1

    Asse1

    Joined:
    Jan 9, 2013
    Posts:
    89
    *Dsch* A hint from the .Net documentation for the TcpClient() constructor,

    But using the IPv6 family to initialize and hand over the IPv6-Addresse leads to the same error when I'm connected to another network.

    It's like I have to try if the IPv6 version works and if it doesn't I use the IPv4 version. Also Socket.OsSupportsIPv6 returns true, which is ok but that doesn't mean that your connection supports IPv6.

    How do I know which version I have to use?
     
    Last edited: Jun 23, 2016
  4. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,931
    @Asse1

    I don't think there is a great solution to this issue. As you mentioned, you probably need to try one network, then fall back to the other one if it first does not work. IPv4 and IPv6 are completely separate networks, so you could be operating in one or both.

    My recommendation would be to try IPv4 first, then fall back to IPv6 if IPv4 is not available.
     
  5. Asse1

    Asse1

    Joined:
    Jan 9, 2013
    Posts:
    89
    Hey Josh,

    yes that's how I've currently implemented the IPv6-support but getting an approval from someone that knows what he's talking about is very important to me. Thanks a lot!
     
  6. Nicolas1212

    Nicolas1212

    Joined:
    Dec 18, 2014
    Posts:
    139
    Hi @Asse1

    This is what we do in our app as well - try IPv4 first, then try IPv6, passing the AddressFamily to the constructor of the TcpClient.

    As far as I know, .Net 4.0 has dual sockets, so if in the future Unity updates its implementation, this will be less of a problem.

    As an aside, we also found big differences between the .Net and .Net 2.0 Subset settings on Android, which might explain your Connect/AsyncConnect problems: https://fogbugz.unity3d.com/default.asp?804510_c5ei44diq6ktnh1u
     
  7. magonicolas

    magonicolas

    Joined:
    Dec 4, 2013
    Posts:
    30
    Can you help me out, I tested the client with a native app and is working, but my unity client app is not! here is my code: (This line is failing, the connection: TcpClient client = new TcpClient("192.168.0.15", port);)
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. using System.Collections.Generic;
    7. using System.Text.RegularExpressions;
    8. using System.Runtime.Serialization.Formatters.Binary;
    9. using System;
    10. using System.IO;
    11. using Newtonsoft.Json;
    12. using System.Net;
    13. using System.Net.Sockets;
    14. using UnityEngine.Networking;
    15.  
    16. using System.Text;
    17.  
    18.  
    19. public class SockMan : MonoBehaviour {
    20.  
    21.     public Text myText;
    22.  
    23.     private bool socketReady;
    24.     private TcpClient socket;
    25.     private NetworkStream stream;
    26.     private StreamWriter writer;
    27.     private StreamReader reader;
    28.  
    29.     void Start() {
    30.         print("Start");
    31.         //ConnectToServer();
    32.         _clientSocket();
    33.     }
    34.  
    35.     public void ConnectToServer() {
    36.         print("Setup");
    37.         myText.text = "Setup...";
    38.         if(socketReady)
    39.             return;
    40.         String host = "192.168.0.15";
    41.         Int32 port = 8080;
    42.  
    43.         //try {
    44.             print("Enter Try");
    45.             myText.text = "Enter Try...";
    46.             socket = new TcpClient(host, port);
    47.             myText.text = "1";
    48.             stream = socket.GetStream();
    49.             myText.text = "2";
    50.             writer = new StreamWriter(stream);
    51.             myText.text = "3";
    52.             reader = new StreamReader(stream);
    53.             myText.text = "4";
    54.             socketReady = true;
    55.             myText.text = "Connected!";
    56.             Send("{ \"type\": \"video\", \"value\": \"2.mp4\"}");
    57.             //myText.text = "5";
    58.         //} catch {}
    59.     }
    60.  
    61.     private void Update() {
    62.         if(socketReady) {
    63.             if(stream.DataAvailable) {
    64.                 string data = reader.ReadLine();
    65.                 if(data != null)
    66.                     OnIncomingData(data);
    67.             }
    68.         }
    69.     }
    70.  
    71.     private void OnIncomingData(string data) {
    72.         print("Server: " + data);
    73.     }
    74.  
    75.     private void Send(string data) {
    76.         myText.text = "Will send";
    77.         if (socketReady) {
    78.             myText.text = "Socket Ready";
    79.             writer.WriteLine(data);
    80.             myText.text = "5";
    81.             writer.Flush();
    82.             myText.text = "6";
    83.             myText.text = "Sent";
    84.         }
    85.     }
    86. }
    87.  
     
  8. sergienko88

    sergienko88

    Joined:
    Jul 22, 2013
    Posts:
    22
    Looks like my problem.Unity 2017.2.0f3 net 4.5 mono. on some androids version connect via NAT64 works, but android 7.1.1 (lg q6) cant do it
     
    Last edited: Dec 12, 2017
  9. Xuejia

    Xuejia

    Joined:
    Aug 2, 2017
    Posts:
    7
    The same problem like sergienko88 and magonicolas.
    Unity 2017.2p and Win10,android can not connect using tcpClient.
    Works well on Unity 5.4
     
  10. Xuejia

    Xuejia

    Joined:
    Aug 2, 2017
    Posts:
    7
    Ok..my problem solved by turn off the fireWall