Соединение меньше TCP клиент-серверное приложение в Delphi - PullRequest
0 голосов
/ 25 ноября 2011

Я создаю приложение клиент-сервер для непрерывной потоковой передачи изображений, чтобы работать как приложение потокового видео.

Клиентское приложение имеет таймер, который каждые 300 мс тикает, чтобы отправить запрос на сервер, и сервер отвечает с изображением.

Реализация работает нормально, но через некоторое время (~ через 5 минут или более) оба приложения зависают без каких-либо сообщений об ошибках (но очень редко я получаю сообщение из системного ресурса)

Раньше это было еще хуже (зависает через ~ 15 секунд), но я изменил idtcpserver1.terminatewaittime to 10 (from 5000 defalt) теперь это происходит через 5 минут.

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

Могу ли я преобразовать tcpserver в ненадежный протокол без установления соединения, чтобы сделать его быстрее и уменьшить нагрузку на запрос.

Но я не хочу использовать UDP, так как он не может обнаружить ошибку повреждения (но мне не нужно исправление, я только хочу знать, есть ли ошибка (чтобы игнорировать все изображение))

procedure server.IdTCPServer1Execute(AContext: TIdContext);
begin
LLine := AContext.Connection.IOHandler.ReadLn();
AContext.Connection.IOHandler.Write(ast, 0, true);
end;

procedure client.timertick(Sender: TObject);
begin
IdTCPClient1.IOHandler.WriteLn(Edit1.Text);
LLine := TMemoryStream.Create;
IdTCPClient1.IOHandler.ReadStream(LLine, -1, false);
end;

предоставлен только исходный код, относящийся к Indy, другие удержаны

=============== обновлено После Реми Лебо - Ответы TeamB и Арно Буше ==========

Спасибо замерзание из-за недоступного изображения в определенных ситуациях. Упомянутые ими инструменты помогли мне отследить проблему

Но все же главная проблема не решена

Могу ли я преобразовать tcpserver в ненадежный протокол без установления соединения, чтобы сделать его быстрее и уменьшить нагрузку на запрос.

Ответы [ 2 ]

4 голосов
/ 26 ноября 2011

Код timertick, который вы показали как утечки памяти.Вы не освобождаете созданный вами TMemoryStream, который, в свою очередь, приводит к утечке памяти, выделяемой внутренним потоком.

Свойство TerminateWaitTimeout не влияет на поведение соединений во время выполнения.Он используется только при завершении работы сервера, чтобы указать, как долго сервер ожидает завершения активных соединений.

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

3 голосов
/ 25 ноября 2011

У вас есть утечка ресурсов.

Возможно, вы не освобождаете свои сетевые ресурсы или ресурс GDI.

  • Сначала нужно запустить ProcessExplorer , затемпосмотрите, сколько обработчиков создает ваше приложение и сколько соединений создано;
  • Затем запустите FastMM4 в режиме обнаружения утечек памяти ;
  • Если ваши ресурсы не сопоставленыс классами Delphi попробуйте найти в своем коде, как они распределяются / освобождаются (используя команду Find IDE с именами вызовов API);
  • Это может быть связано с проблемой многопоточности - возможно, с каким-либо условием гонки - попробуйте блокировка ваших общих ресурсов;
  • Использование механизма ведения журнала для отслеживания происходящего в вашем процессе, особенно для всех классов Indy;
  • См.другие подсказки в этом ответе StackOverflow .

Что интересно с UDP, так это то, что вы можете транслировать свой поток одновременно нескольким целям.Потеря потенциальных пакетов компенсируется уменьшением использования полосы пропускания в случае увеличения номера клиента.Стоит посмотреть в этом направлении, если вам нужна локальная трансляция с ограниченным использованием ресурсов (но это будет сложнее через Интернет).

...