0
\$\begingroup\$

For my Unity game I have a Client-Server model, and I want both sides to ping each other repeatedly to make sure I know what latency between players is. In the server's case, a client connects and their details are logged. Their details are then used when the game creates coroutines. This coroutine starts a loop which pings and waits and pings and waits, etc, until the game ends.

However, it doesn't work. The debug messages are throwing up strange results. It attempts to ping to IP "::ffff:192.168.0.10", and then is waiting forever. I don't suppose the fact I am running this via Unity editor and another app window on the same machine should be an issue? What is the "::ffff" about in the IP it saves when a client connects? Is that the issue? If so, how can I best format it properly?

Yes, I need to add another loop in the coroutine to make it go forever. Once would be a nice start though.

CLIENT CONNECTS TO SERVER

    // Recieve data from all.
    NetworkEventType recData = NetworkTransport.Receive(out socketId, out connectionId, out channelId, buffer, bufferSize, out dataSize, out error);

    switch (recData)
    {
        case NetworkEventType.ConnectEvent:
            if (localConnectionId == connectionId)
            {
                // My active connect request approved.
                Debug.Log("Connection request approved.");
            }
            else // New client.
            {
                string outIp;
                int outPort;
                UnityEngine.Networking.Types.NetworkID outNetwork;
                UnityEngine.Networking.Types.NodeID dstNode;
                byte outError;
                NetworkTransport.GetConnectionInfo(socketId, connectionId, out outIp, out outPort, out outNetwork, out dstNode, out outError);
                AllocateNewLobbyPlayer(socketId, connectionId, channelId, outIp, outPort);
            }
            break;
   }

CREATE PING LOOP COROUTINES

    for (int i = (Game.isServer) ? 1 : 0; i < lobbyPlayers.Length; i++)
    {
        if (lobbyPlayers[i] != null)
        {
            Debug.Log(" STARTED PING FOR " + i);
            StartCoroutine(PingTest(lobbyPlayers[i].ip));
        }
    }

PING LOOP COROUTINE

protected IEnumerator PingTest(string ip)
{
    Ping ping = new Ping(ip);
    Debug.Log(" SENT PING " + ip);
    while (!ping.isDone)
    {
        Debug.Log("WAITING");
        yield return new WaitForFixedUpdate();
    }
    Debug.Log(" PING COMPLETED " + ping.time);
    yield return new WaitForFixedUpdate();
}

DEBUG OUTPUT

 STARTED PING FOR 1
 SENT PING ::ffff:192.168.0.10
 WAITING
 WAITING
 WAITING

etc, etc, etc...

\$\endgroup\$
  • 1
    \$\begingroup\$ "::ffff:192.168.0.10" that's a transitional IPv6 address. Can you open up a command prompt and ping 192.168.0.10? \$\endgroup\$ – Jimmy Nov 9 '17 at 21:15
  • \$\begingroup\$ @Jimmy I can't test that right now (though I will soon) but is this to say you can't see anything else wrong? Or that this just the most obvious problem? \$\endgroup\$ – inappropriateCode Nov 10 '17 at 12:56
  • \$\begingroup\$ I suspect a regular ping will timeout as well, so this would be the next thing I test. I imagine the address formatting is not really issue. \$\endgroup\$ – Jimmy Nov 10 '17 at 15:22
  • \$\begingroup\$ @Jimmy Turns out, it was. Removed ::ffff: from string and worked perfectly. Admittedly I changed the ping class code a bit but the problem was basically it mapping a ipv4 to pseudo ipv6 prefix or something. Need to be just ipv4 format. \$\endgroup\$ – inappropriateCode Dec 8 '17 at 10:02
  • 1
    \$\begingroup\$ glad you got it worked out! You should write up your results in an answer for future readers. \$\endgroup\$ – Jimmy Dec 8 '17 at 10:04
1
\$\begingroup\$

Ping is implemented differently on different platforms.

On some platforms, it's an ICMP Echo Request (the thing that happens when you enter ping [ip-address] in your command shell). These might be blocked by firewalls or routers which do not block the normal game traffic. On others it tries to open a HTTP connection to port 80, which of course doesn't do much if the target IP does not run a webserver.

If what you actually want to do is check the quality of the game connection, you are better off implementing your own Ping message as part of your game's network protocol.

\$\endgroup\$
  • \$\begingroup\$ When you say implementing your own solution, in Unity's case, would this be, say, sending a simple object on a unique connection channel, which logs the round trip time? Since that's basically what is necessary, just always knowing what the current ping time is? \$\endgroup\$ – inappropriateCode Nov 10 '17 at 15:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.