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

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

8 голосов
/ 05 декабря 2010

Я делаю 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 ]

13 голосов
/ 05 декабря 2010

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

3 голосов
/ 06 декабря 2010

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

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

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

Но если у вас нет таких требований "низкой загрузки ЦП", лучше подумайте об использовании TCP / IP вместо UDP / IP. Например, если вам нужна трансляция, используйте UDP, но с каким-то механизмом ACK.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...