Pregunta

Estoy trabajando en C# aplicación de Servidor para un motor de juego que estoy escribiendo en ActionScript 3.Estoy usando un servidor autoritativo modelo como para evitar las trampas y garantizar el juego justo.Hasta ahora todo funciona bien:

Cuando el cliente empieza a moverse, se dice que el servidor y se inicia la representación local;el servidor, a continuación, le dice a los demás de que el cliente X se comenzó a moverse, entre los detalles para que también ellos puedan comenzar a producir.Cuando el cliente deja de moverse, se dice que el servidor, el cual realiza los cálculos basados en el momento en que el cliente comenzó a moverse y el cliente de procesamiento de la garrapata de demora y las respuestas a todo el mundo, por lo que puede actualizar con los valores correctos.

La cosa es que cuando puedo usar el valor predeterminado de 20 ms garrapata retraso en el servidor cálculos, cuando el cliente se mueve de un lugar de larga distancia, hay una notable inclinación hacia delante, cuando se detiene.Si puedo aumentar ligeramente el retraso a 22ms, en mi red local todo funciona muy bien, pero en otros lugares, la inclinación es todavía allí.Después de experimentar un poco, me di cuenta de que el retardo adicional necesaria es bastante ligada a la latencia entre el cliente y el servidor.Incluso me hierve abajo a una fórmula que funciona bastante bien:delay = 20 + (latencia / 10).

Entonces, ¿cómo debo proceder para obtener la latencia entre un determinado cliente y el servidor (estoy usando asincrónica sockets).La CPU esfuerzo no puede ser demasiado, como para no tener el servidor se ejecute lentamente.También, es esta realmente la mejor manera, o es que hay un más eficiente y más fácil manera de hacer esto?

¿Fue útil?

Solución

Siento que esto no responder directamente a su pregunta, pero generalmente hablando, usted no debe confiar demasiado en la medición de la latencia porque puede ser bastante variable.No sólo eso, usted no sabe si el ping de tiempo que se mide es incluso simétrica, que es importante.No hay punto de aplicación de 10 ms de latencia de corrección, si resulta que el tiempo de ping de 20ms es en realidad 19ms desde el servidor al cliente y 1ms desde el cliente al servidor.Y la latencia de la aplicación de los términos no es el mismo, ya que en redes - usted puede ser capaz de hacer ping a una máquina y obtener una respuesta en 20ms pero si usted se pone en contacto con un servidor en la máquina que sólo los procesos de la red de entrada de 50 veces por segundo y, a continuación, sus respuestas serán retrasado por un extra de 0 a 20 ms, y esto va a variar bastante impredecible.

Eso no quiere decir que la latencia de medición no tiene un lugar en la suavización de las predicciones, pero no va a resolver tu problema, simplemente limpie un poco.

En la cara de ella, aquí el problema parece ser que el que envía la información en el primer mensaje que se utiliza para extrapolar los datos de hasta que el último mensaje es recibido.Si todo lo demás permanece constante, entonces el movimiento del vector dado en el primer mensaje multiplicada por el tiempo entre los mensajes que le dará el servidor de la correcta posición final que el cliente estaba en aproximadamente ahora-en la latencia (/2).Pero si la latencia de todo tipo de cambios, el tiempo entre los mensajes se aumentará o disminuirá.El cliente puede saber él se trasladó a 10 unidades, pero el servidor simulado él en movimiento 9 o 11 unidades antes de que se le dijo a complemento de vuelta con 10 unidades.

La solución general a este problema es no asumir que la latencia va a permanecer constante, pero para enviar periódicamente la posición de las actualizaciones, que permiten al servidor para comprobar y corregir la posición del cliente.Con solo 2 mensajes como el que tiene ahora, todo el error es descubierto y corregido después de la 2ª mensaje.Con más mensajes, el error se propaga a lo largo de muchos más puntos de la muestra, permitiendo más suave y menos visibles de la corrección.

Nunca puede ser perfecto, aunque:todo lo que toma es un lag spike en la última milésima de segundo de movimiento y el servidor de la representación de la voluntad de sobreimpulso.Usted no puede conseguir alrededor de que si vas a predecir el futuro de movimiento basado en eventos pasados, ya que no hay alternativa real a la elección, ya sea la correcta-pero-tardía o incorrecta-pero-en su momento ya que la información se toma tiempo para viajar.(La Culpa De Einstein.)

Otros consejos

Una cosa a tener en cuenta cuando se utiliza ICMP basado en los pings es que los equipos de red se dan a menudo el tráfico ICMP una prioridad menor que la normal paquetes, especialmente cuando los paquetes se cruzan los límites de la red, tales como los enlaces WAN.Esto puede conducir a pings se ha caído o que muestran una mayor latencia que el tráfico es realmente experimentando y se presta a ser un indicador de problemas en lugar de una herramienta de medición.

El aumento en el uso de Calidad de Servicio (QoS) en redes sólo agrava este y, como consecuencia, a pesar de ping sigue siendo una herramienta útil, es necesario que se entienda que no puede ser un fiel reflejo de la latencia de la red para no ICMP basado real de tráfico.

Hay un buen post en el Itrinegy blog ¿Cómo se puede medir la Latencia (RTT) en una red en estos días? acerca de este.

Usted podría utilizar los ya disponibles Ping Clase.Debe ser preferido frente a la escritura de su propio TRABAJO.

Tiene un comando "ping", donde usted envía un mensaje desde el servidor hasta el cliente, entonces cuánto tiempo se tarda en obtener una respuesta.De restricción de sobrecarga de la CPU escenarios, debe ser bastante fiable.Para conseguir el viaje de ida el tiempo, solo hay que dividir el tiempo por 2.

Podemos medir la viaje redondo tiempo el uso de la Ping la clase de los .NET Framework.

Crear una instancia de un Ping y suscríbete a la PingCompleted evento:

Ping pingSender = new Ping();
pingSender.PingCompleted += PingCompletedCallback;

Agregar código para configurar la acción y el ping.

Nuestro PingCompleted controlador de eventos (PingCompletedEventHandler) tiene un PingCompletedEventArgs argumento.El PingCompletedEventArgs.Reply nos llega una PingReply objeto. PingReply.RoundtripTime devuelve el tiempo de ida y vuelta (el "número de milisegundos que tarda para enviar un Mensaje de Control de Internet (ICMP) de solicitud de eco y recibir el correspondiente mensaje de respuesta de eco de ICMP"):

public static void PingCompletedCallback(object sender, PingCompletedEventArgs e)
{
    ...
    Console.WriteLine($"Roundtrip Time: {e.Reply.RoundtripTime}");
    ...
}

Código de descarga de un completo ejemplo de trabajo, basado en MSDN ejemplo.He modificado para escribir el RTT para la consola:

public static void Main(string[] args)
{
    string who = "www.google.com";
    AutoResetEvent waiter = new AutoResetEvent(false);

    Ping pingSender = new Ping();

    // When the PingCompleted event is raised,
    // the PingCompletedCallback method is called.
    pingSender.PingCompleted += PingCompletedCallback;

    // Create a buffer of 32 bytes of data to be transmitted.
    string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    byte[] buffer = Encoding.ASCII.GetBytes(data);

    // Wait 12 seconds for a reply.
    int timeout = 12000;

    // Set options for transmission:
    // The data can go through 64 gateways or routers
    // before it is destroyed, and the data packet
    // cannot be fragmented.
    PingOptions options = new PingOptions(64, true);

    Console.WriteLine("Time to live: {0}", options.Ttl);
    Console.WriteLine("Don't fragment: {0}", options.DontFragment);

    // Send the ping asynchronously.
    // Use the waiter as the user token.
    // When the callback completes, it can wake up this thread.
    pingSender.SendAsync(who, timeout, buffer, options, waiter);

    // Prevent this example application from ending.
    // A real application should do something useful
    // when possible.
    waiter.WaitOne();
    Console.WriteLine("Ping example completed.");
}

public static void PingCompletedCallback(object sender, PingCompletedEventArgs e)
{
    // If the operation was canceled, display a message to the user.
    if (e.Cancelled)
    {
        Console.WriteLine("Ping canceled.");

        // Let the main thread resume. 
        // UserToken is the AutoResetEvent object that the main thread 
        // is waiting for.
        ((AutoResetEvent)e.UserState).Set();
    }

    // If an error occurred, display the exception to the user.
    if (e.Error != null)
    {
        Console.WriteLine("Ping failed:");
        Console.WriteLine(e.Error.ToString());

        // Let the main thread resume. 
        ((AutoResetEvent)e.UserState).Set();
    }

    Console.WriteLine($"Roundtrip Time: {e.Reply.RoundtripTime}");

    // Let the main thread resume.
    ((AutoResetEvent)e.UserState).Set();
}

Es posible que desee realizar varios pings y luego calcular un promedio, dependiendo de los requisitos del curso.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top