2010-12-05 44 views
8

Estoy haciendo un UDP C/S. Tengo un problema con la cantidad de datos que el servidor puede recibir por segundo.Servidor UDP y Cliente en Delphi

He probado el envío de lotes de 10, 100, 1000 mensajes de datos al servidor, 10, 100 recibidos sin ningún problema. cuando se envía 1000, solo se reciben 300 ~ 400. Todas las pruebas hechas localmente.

He intentado implementar el servidor utilizando tanto el twosecket de ICS como el tudpblocksocket de Synapse. Ambos resultaron con el mismo problema anterior.

¿Podría alguno explicarme por qué sucede esto y cómo podría mejorar el rendimiento del servidor?

Código usando TUDPBlockSocket

...

while not Terminated do 
begin 
    try 
    sz := FUDPServer.WaitingData; 
    if sz > 0 then 
    begin 
     FUDPServer.RecvBuffer(mem.Memory, sz); 
     mem.Seek(0, 0); 
     AMessage := fFormats.ReadFromStream(mem); 
     DoMessageReceived(FUDPServer.RemoteSin.sin_addr, AMessage); 
    end; 

    finally 

    end; 
end; 

...

código usando ICS

...

procedure TShapeServer.WSocketDataAvailable(Sender: TObject; ErrCode: Word); 
... 
begin 
    SrcLen := SizeOf(Src); 
    stream := TMemoryStream.Create; 
    stream.SetSize(INT_BUFFER_SIZE); 
    Inc(fMessageReceived); 
    try 
    Len := FUDPServer.ReceiveFrom(stream.Memory, stream.size, Src, SrcLen); 
    if (FSenderAddr.S_addr = INADDR_ANY) or 
     (FSenderAddr.S_addr = Src.Sin_addr.S_addr) then 
    begin 

     while stream.Position < Len do 
     begin 
     try 
      AMessage := fFormats.ReadFromStream(stream); 
      DoMessageReceived(Src.Sin_addr, AMessage); 
     except 
      break; 
     end; 
     end; 

    end; 

    finally 
    stream.Free; 
    end; 
end; 
... 
+0

¿Se puede registrar el tráfico udp loopback utilizando wireshark (en Windows funciona con winpcap)? –

+0

También vería el límite de "seguridad" de Microsoft del paquete por segundo. IIRC, tcpip.sys informó acción de límite al registro de eventos –

+0

Intenté wireshark. No estoy seguro de haberlo hecho mal, pero hay un adaptador de bucle para que yo elija. :(Gran herramienta si – Darkerstar

Respuesta

13

UDP no garantiza entrega de mensaje - si no hay lugar en el búfer, el paquete se descarta sin vacilación. Si necesita una entrega garantizada, use TCP y cree un esquema de comunicación basado en mensajes sobre TCP. O use nuestro producto MsgConnect que ya lo tiene. Nota para los cruzados: MsgConnect tiene una versión de código abierto.

+1

+1 muy buena respuesta! – ComputerSaysNo

+0

Entonces, ¿hay alguna manera de hacer que el búfer sea más grande, o de trabajar más rápido en el contenido del búfer? –

+3

@Rob y ¿cuál es el motivo? Incluso si pudiera hacer un búfer enorme (y no se puede), no tendría una garantía de que bajo una carga más pesada el tamaño del búfer sería suficiente. Y la caída de paquetes en ese caso causaría errores difíciles de rastrear.Por lo tanto, es mejor no usar arquitectura "defectuosa" (para este propósito concreto) –

3

Si desea utilizar el protocolo UDP y no perder ningún paquete, tendrá que agregar un mecanismo de Reconocimiento a su programa, ya que los paquetes UDP pueden perderse durante la transmisión. Este mecanismo ACK ya está implementado en el protocolo TCP, por lo que es la mejor opción para el rendimiento y la coherencia.

Si no puede usar TCP (tal vez su cliente no tenga suficiente potencia de CPU o RAM para manejar TCP), considere usar algún protocolo basado en UDP fácil de codificar, como TFTP. Implementamos un cliente y servidor TFTP a través de nuestro SynCrtUnit, pero tiene dicho componente en Synapse. Pero TFTP es lento, porque espera una señal ACK para cada paquete transmitido. Por lo tanto, no perderá ningún paquete, pero la velocidad será baja, en comparación con TCP.

El año pasado, implementé dicho servidor TFTP en Delphi, luego un cliente TFTP en TP 7, en un motor automatizado basado en DOS. Esto funcionaba muy bien, y algunas estructuras de objetos se compartían entre ambos extremos. La pila TFTP/UDP/IP estaba codificada en TP 7 puro, con solo memoria asignada estática, y funcionaba muy bien.

Pero si no tiene esos requisitos de "baja CPU", mejor considere usar TCP/IP en lugar de UDP/IP. Si necesita alguna transmisión, por ejemplo, use UDP, pero con algún tipo de mecanismo ACK.

+0

Gracias, me aseguraré de verificarlo. – Darkerstar

+2

De hecho, cuando crea una comunicación basada en UDP con entrega garantizada, es difícil remover el TCP en velocidad: fue pulido por generaciones de desarrolladores. Es posible (lo hicimos para ciertas tareas y aplicaciones específicas) pero bastante no trivial. Así que ir a la ruta TCP con posibles desconexiones en inactividad es probablemente el mejor enfoque. –

Cuestiones relacionadas