Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 3 131

/ вопрос открыт /

Здравствуйте, эксперты!
Мне нужна стабильная процедура UDP отправки, желательно мультикаст, без привязки к IP клиента. Чтобы она слала данные независимо от того есть клиент, нет и что с ним происходит. В чем моя проблема:
1) использовал компонент IdUDPServer. делаю:
IdUDPServer1.Send(clientIP, clientPort,sendStr);
при отсутствии или отключении клиента вылетает с эксепшеном. Прием сообщений реализован на этом же компоненте, работает без проблем. Как для него сделать широковещательную рассылку и не будет ли это все при этом вылетать просто не знаю.
2) пробовал на сокетах:
sock:=socket(AF_INET,SOCK_DGRAM,0);
AddrTo.sin_family:=AF_INET;
AddrTo.sin_addr.S_addr:=inet_addr (pchar(clientIP));
AddrTo.sin_port:=htons(11000);
StrCopy(PChar(@fSend[0]), PChar(sendStr));
SendTo(sock, fSend, Length(sendStr),0, AddrTo,SizeOf(TSockAddr));
тут все нормально без вылетаний, если бы не одно но: где-то через пол часа сокет как будто засыпает и клиент перестает принимать что-либо до перезапуска приложения.

Приложение:
  1.  
  2. private void StartListener()
  3. {
  4. udpClient1 = new UdpClient(11000);
  5. try
  6. {
  7. while (clientConnected)
  8. {
  9.  
  10. IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any,0);
  11. Byte[] receiveBytes = udpClient1.Receive(ref
  12. RemoteIpEndPoint);
  13. string returnData = Encoding.Default.GetString(receiveBytes, 0, receiveBytes.Length);
  14. recvData(returnData);
  15. }
  16. }
  17. catch
  18. {
  19. MessageBox.Show("Catch!");
  20. }
  21. }


AlexMPEI Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: AlexMPEI (статус: 1-ый класс)
Вопрос отправлен: 27 августа 2009, 13:00
Состояние вопроса: открыт, ответов: 1.

Ответ #1. Отвечает эксперт: min@y™

Не знаю, поможет или нет, но всё-таки я откопал свой старый рабочий модуль и прицепляю к ответу.
К ответу прикреплён файл. Загрузить » (срок хранения: 60 дней с момента отправки ответа)

Ответ отправил: min@y™ (статус: Доктор наук)
Время отправки: 27 августа 2009, 16:33


Мини-форум вопроса

Всего сообщений: 14; последнее сообщение — 3 сентября 2009, 17:20; участников в обсуждении: 2.
Вадим К

Вадим К (статус: Академик), 27 августа 2009, 13:22 [#1]:

По поводу "сокетной версии". При такой рассылке пакеты ведь и Вам назад приходят. А Вы их читаете? А то они забивают очередь и всё...
Галочка "подтверждения прочтения" - вселенское зло.
AlexMPEI

AlexMPEI (статус: 1-ый класс), 27 августа 2009, 14:14 [#2]:

при такой как сейчас - нет (я использую в примере IP клиента, он не мультикастовый). Я могу их читать и пропускать - это не проблема. Главное, как правильно сделать чтобы это работало и не валилось? и второй главный вопрос почему падает при исчезновении клиента если использую IdUDPServer и что происходит с сокетом через пол часа в сокетной версии и как этого избежать.
Вадим К

Вадим К (статус: Академик), 27 августа 2009, 14:20 [#3]:

Что с сокетной версией происходит - наверно просто не читаете и забивается очередь.
А IdUDPServer... у инди свое вИдение UDP...
Галочка "подтверждения прочтения" - вселенское зло.
AlexMPEI

AlexMPEI (статус: 1-ый класс), 27 августа 2009, 14:40 [#4]:

не читаю где? На клиенте? тот кусок что на C# постоянно читает как только что-то приходит. но где-то через пол часа перестает приходить что-либо :) И потом, насколько я знаю в UDP я послал и забыл, мне даже доставку никто не гарантирует.
Вадим К

Вадим К (статус: Академик), 27 августа 2009, 14:47 [#5]:

да. UDP - это послал-забыл. Но если они приходят - надо читать. А если буфер забили, то наверное и не будет даже и писаться, пока не вычитать. Читать надо и тем, кто отсылает. Вы уверены, что он ничего не получает?

А шарп... это отдельная песня.
Галочка "подтверждения прочтения" - вселенское зло.
AlexMPEI

AlexMPEI (статус: 1-ый класс), 27 августа 2009, 15:03 [#6]:

Клиент: КПК с программой на Visual Studio C#. кусок кода на C# - это поток приема, который постоянно крутится и не вываливается когда начинается данная проблема. Как только что-то приходит - он сразу читает. После "засыпания" поток повисает в ожидании очередного пакета, но его нет и не будет пока приложение не будет перезапущено. Средняя частота посылок раз в секунду. При использовании IdUDPServer вся прием-передача проходит так же, но "засыпания" на сервере не происходит, зато есть вылет с ошибкой при пропадании клиента.
Как читать тому кто отсылает то что он послал кому-то конкретному (не себе и не мультикаст) я не понимаю. от сервера к серверу ничего не вернется в этом случае.
AlexMPEI

AlexMPEI (статус: 1-ый класс), 27 августа 2009, 15:32 [#7]:

Сейчас еще раз взглянул повеимательнее... блок
sock:=socket(AF_INET,SOCK_DGRAM,0);
AddrTo.sin_family:=AF_INET;
AddrTo.sin_addr.S_addr:=inet_addr (pchar(clientIP));
AddrTo.sin_port:=htons(11000);
я выполняю каждый раз при посылке. Т.е. каждый раз я создаю сокет и в конце его даже не закрываю. Может, я выбираю массив всех доступных сокетов и на этом наступает сокетный коллапс?
Вадим К

Вадим К (статус: Академик), 27 августа 2009, 16:03 [#8]:

больше 10000 на один процесс сокетов не удастся набрать. ну если реестр покрутить, то 16тыс с копейками.
Да, на лицо утечка ресурсов. Отправил - закрыл. или открывать при старте и закрывать по завершению.
Галочка "подтверждения прочтения" - вселенское зло.
AlexMPEI

AlexMPEI (статус: 1-ый класс), 27 августа 2009, 16:22 [#9]:

Поправил я этот момент уже. Сейчас тест крутится уже больше получаса, пока вроде все Ок. Наверное, действительно проблема была именно в этом.
Но что случается с Indy для меня все равно остается загадкой.
Вадим К

Вадим К (статус: Академик), 27 августа 2009, 17:06 [#10]:

вот теперь улеглось. шарп просто вызывает деструктор автоматом по выходу с блока. а деструктор для UDP класса содержит закрытие сокета.
А у инди местами свое трактование как стандартов, так и rfc.
Галочка "подтверждения прочтения" - вселенское зло.
AlexMPEI

AlexMPEI (статус: 1-ый класс), 28 августа 2009, 08:53 [#11]:

Интересная особенность... спасибо за помощь. 15 часов теста - все Ок.
Вадим К

Вадим К (статус: Академик), 28 августа 2009, 14:57 [#12]:

вот, а так рождаются мифы, что на делфи нельзя написать, код плохой генерируется...
А всего то надо "следить за собой и убирать мусор".
Галочка "подтверждения прочтения" - вселенское зло.
AlexMPEI

AlexMPEI (статус: 1-ый класс), 3 сентября 2009, 17:04 [#13]:

Развитие функциональности: 1 сервер на Делфи, несколько клиентов на С# (Windows mobile, Visual studiо C#). все клиенты дублируют друг друга (Могут посылать независимо команды, а от сервера одновременно получают одинаковую информацию). Что посоветуете по организации такой структуры обмена? Я думаю, что тут уж точно UDP надо применять - широковещательная рассылка по всем клиентам. Какие лучше компоненты Делфи использовать?
Вадим К

Вадим К (статус: Академик), 3 сентября 2009, 17:20 [#14]:

А чем вышепримененная не подходит? или клиенты могут быть в разных подсетях?
Галочка "подтверждения прочтения" - вселенское зло.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:56
Выполнено за 0.02 сек.