|
Вопрос # 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));
тут все нормально без вылетаний, если бы не одно но: где-то через пол часа сокет как будто засыпает и клиент перестает принимать что-либо до перезапуска приложения.
Приложение: Переключить в обычный режим-
- private void StartListener()
- {
- udpClient1 = new UdpClient(11000);
- try
- {
- while (clientConnected)
- {
-
- IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any,0);
- Byte[] receiveBytes = udpClient1.Receive(ref
- RemoteIpEndPoint);
- string returnData = Encoding.Default.GetString(receiveBytes, 0,
receiveBytes.Length);
- recvData(returnData);
- }
- }
- catch
- {
- MessageBox.Show("Catch!");
- }
- }
 |
Вопрос задал: 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 (статус: 1-ый класс), 27 августа 2009, 14:14 [#2]:
при такой как сейчас - нет (я использую в примере IP клиента, он не мультикастовый). Я могу их читать и пропускать - это не проблема. Главное, как правильно сделать чтобы это работало и не валилось? и второй главный вопрос почему падает при исчезновении клиента если использую IdUDPServer и что происходит с сокетом через пол часа в сокетной версии и как этого избежать.
|
|
Вадим К (статус: Академик), 27 августа 2009, 14:20 [#3]:
Что с сокетной версией происходит - наверно просто не читаете и забивается очередь.
А IdUDPServer... у инди свое вИдение UDP...
Галочка "подтверждения прочтения" - вселенское зло.
|
|
AlexMPEI (статус: 1-ый класс), 27 августа 2009, 14:40 [#4]:
не читаю где? На клиенте? тот кусок что на C# постоянно читает как только что-то приходит. но где-то через пол часа перестает приходить что-либо И потом, насколько я знаю в UDP я послал и забыл, мне даже доставку никто не гарантирует.
|
|
Вадим К (статус: Академик), 27 августа 2009, 14:47 [#5]:
да. UDP - это послал-забыл. Но если они приходят - надо читать. А если буфер забили, то наверное и не будет даже и писаться, пока не вычитать. Читать надо и тем, кто отсылает. Вы уверены, что он ничего не получает?
А шарп... это отдельная песня.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
AlexMPEI (статус: 1-ый класс), 27 августа 2009, 15:03 [#6]:
Клиент: КПК с программой на Visual Studio C#. кусок кода на C# - это поток приема, который постоянно крутится и не вываливается когда начинается данная проблема. Как только что-то приходит - он сразу читает. После "засыпания" поток повисает в ожидании очередного пакета, но его нет и не будет пока приложение не будет перезапущено. Средняя частота посылок раз в секунду. При использовании IdUDPServer вся прием-передача проходит так же, но "засыпания" на сервере не происходит, зато есть вылет с ошибкой при пропадании клиента.
Как читать тому кто отсылает то что он послал кому-то конкретному (не себе и не мультикаст) я не понимаю. от сервера к серверу ничего не вернется в этом случае.
|
|
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 (статус: 1-ый класс), 27 августа 2009, 16:22 [#9]:
Поправил я этот момент уже. Сейчас тест крутится уже больше получаса, пока вроде все Ок. Наверное, действительно проблема была именно в этом.
Но что случается с Indy для меня все равно остается загадкой.
|
|
Вадим К (статус: Академик), 27 августа 2009, 17:06 [#10]:
вот теперь улеглось. шарп просто вызывает деструктор автоматом по выходу с блока. а деструктор для UDP класса содержит закрытие сокета.
А у инди местами свое трактование как стандартов, так и rfc.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
AlexMPEI (статус: 1-ый класс), 28 августа 2009, 08:53 [#11]:
Интересная особенность... спасибо за помощь. 15 часов теста - все Ок.
|
|
Вадим К (статус: Академик), 28 августа 2009, 14:57 [#12]:
вот, а так рождаются мифы, что на делфи нельзя написать, код плохой генерируется...
А всего то надо "следить за собой и убирать мусор".
Галочка "подтверждения прочтения" - вселенское зло.
|
|
AlexMPEI (статус: 1-ый класс), 3 сентября 2009, 17:04 [#13]:
Развитие функциональности: 1 сервер на Делфи, несколько клиентов на С# (Windows mobile, Visual studiо C#). все клиенты дублируют друг друга (Могут посылать независимо команды, а от сервера одновременно получают одинаковую информацию). Что посоветуете по организации такой структуры обмена? Я думаю, что тут уж точно UDP надо применять - широковещательная рассылка по всем клиентам. Какие лучше компоненты Делфи использовать?
|
|
Вадим К (статус: Академик), 3 сентября 2009, 17:20 [#14]:
А чем вышепримененная не подходит? или клиенты могут быть в разных подсетях?
Галочка "подтверждения прочтения" - вселенское зло.
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|