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.