UDP-сервер и клиент в Delphi

Я делаю UDP C / S. У меня проблема с количеством данных, которые сервер может получать в секунду.

я протестировал отправку пакетов 10, 100, 1000 сообщений данных на сервер, 10, 100, полученных без проблем. при отправке 1000, только 300 ~ 400 получили. Все тесты сделаны локально.

Я попытался реализовать сервер, используя как twsocket ICS, так и Tudpblocksocket Synapse. Как оказалось, с такой же проблемы.

может ли объяснить мне, почему это происходит, и как я могу улучшить производительность сервера.

код с помощью 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;

...

код с использованием 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;
...

2 ответов


UDP не гарантирует доставку сообщений - если в буфере нет места, пакет отбрасывается без колебаний. Если вам нужна гарантированная доставка, используйте TCP и постройте схему связи на основе сообщений поверх TCP. Или используйте наш MsgConnect продукт, который уже есть. Примечание для крестоносцев: MsgConnect имеет версию с открытым исходным кодом.


Если вы хотите использовать протокол UDP и не потерять пакет, вам придется добавить механизм подтверждения в свою программу, потому что UDP-пакеты могут потеряться во время передачи. Этот механизм ACK уже реализован в протоколе TCP, поэтому это лучший выбор для производительности и согласованности.

Если вы не можете использовать TCP (возможно, у вашего клиента недостаточно мощности процессора или ОЗУ для обработки TCP), рассмотрите возможность использования простого в коде протокола UDP, такого как TFTP. Мы осуществили клиент и сервер TFTP над нашим SynCrtUnit, но у вас есть такой компонент в синапс. Но TFTP медленный, потому что он ждет сигнала ACK для каждого переданного пакета. Таким образом, вы не потеряете ни одного пакета, но скорость будет плохой, по сравнению с TCP.

в прошлом году я реализовал такой сервер TFTP в Delphi, затем клиент TFTP в TP 7, в автоматизированном движке на основе DOS. Это отлично работало, и некоторые структуры объектов были разделены между обоими концами. Сервер TFTP/UDP в/ИС стек был закодирован в чистом TP 7, С только статической выделенной памятью, и работал отлично.

но если у вас нет таких "низких требований к процессору", скорее рассмотрите использование TCP/IP вместо UDP/IP. Если вам нужна какая-то трансляция, например, используйте UDP, но с каким-то механизмом ACK.