Конференция "Сети" » Отправка UDP по разным адресам через один сокет
 
  • Anatoly Podgoretsky © (30.01.09 16:27) [20]
    В потоках конечно проще использовать синхронные методы, но ты то не умеешь работать с потоками, видимо реализовал по схеме Архангельского.
  • Сергей М. © (30.01.09 16:35) [21]

    > почему же тогда Apache в одно время может общаться с тысячами
    > клиентов, а?


    Потому что это сервер, создающий для каждого клиента отдельное TCP-соединение.

    А у тебя UDP, который НЕ подразумевает соединение !

    Так что не надо сравнивать кислое с пресным, добежавший ты наш)
  • Добежал (30.01.09 16:48) [22]

    > Потому что это сервер, создающий для каждого клиента отдельное
    > TCP-соединение

    и что дальше? А сам протокол верхнего уровня HTTP синхронный. И у  меня протокол верхнего уровня синхронный. И ты пишешь, что это бред. Ну иди заяви, что протокол HTTP тоже бред.

    Я не спрашиваю как мне идентифицировать устройства. Я спрашиваю как лучше синхронизировать выборку сообщений. Вопрос ИМЕННО В ЭТОМ.
    Если ты хочешь сказать, что это невозможно сделать - то это неправда. Я уже предложил способ, как это можно сделать. И вопрос в том, насколько оптимален этот способ и можно ли сделать лучше.
  • Anatoly Podgoretsky © (30.01.09 16:51) [23]
    > Добежал  (30.01.2009 16:48:22)  [22]

    Метод Synchronize
  • Сергей М. © (30.01.09 17:03) [24]

    > событие придется создавать не на поток, а на каждый запрос


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

    Транспортный поток создает объект-очередь передачи, доступный всем прикл.потокам.

    После своего создания каждый прикладной поток регистририется у транспортного потока, передавая тому параметром хэндл индивидуального объекта синхронизации и получая как результат регистрации ссылку на, например, индивидуальный объект-очередь входящих сообщений, адресованных этому прикл.потоку.

    Трансп.поток берет из очереди передачи сообщения и посылает их адресатам.
    По мере поступления ответных сообщений трансп.поток "сортирует" их на предмет принадлежности ответов тем или иным прикл.потокам, помещая их в соответствующие очереди вх.сообщений и переводя соотв. объект синхр-ции в сигнальное состояние.

    Прил.потоки ждут каждый своего сигнала, после чего выгребают свои очереди и сбрасывают сингал.

    Все !

    Можно и без объектов синхронизации обойтись - прикл.потоки сообщают всем заинтересованным потокам свои идентификаторы и попросту засыпают, если им нечего передавать или очереди приема пусты. Достаточно разбудить прикл.поток для того чтобы он возобновил свой прикладной цикл.
  • Slym © (30.01.09 17:27) [25]
    Как обычно вода в ступе...
    Не ветка помойка...
    По сабжу...
    Решение задачи возможно только при следующих условиях - уникальности и точной идентификации входящих пакетов!
    Т.е. если отдельная задача тебует общения с устройством с уникальной парой RemoteIP:RemotePORT!

    потоки передают сообщение, адресат (IP:PORT) и объект для ответа (колбек функция, объект синхронизации (евент)) транспортному потоку

    send(msg:string;ip:string;port:word;callback:procedure)

    травспортный поток заносит в свою внутреннюю таблицу ключ IP:PORT и соответствующий ему объект от
    IP:port=callback
    и отправляет сообщение...
    при приходе ответа в таблице по ключу RemoteIP:RemotePort ищется калбек и при нахождении вызывается с принятым сообщением
  • Slym © (30.01.09 17:28) [26]
    по типу NAT таблицы и преобразования пакетов
  • Добежал (30.01.09 17:34) [27]

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


    писать надоело, с вашего позволения буду цитировать:


    > Из-за плагиновой системы предсказать сколько потоков гипотетически
    > могут вызвать транспортные функции - невозможно.


    Таким образом написанное далее ниже смысла не имеет.
  • Добежал (30.01.09 17:54) [28]
    О, ну хоть кто-то что-то по делу начал писать, сразу видно человек в курсе проблемы.


    > Решение задачи возможно только при следующих условиях -
    > уникальности и точной идентификации входящих пакетов!

    такое условие есть.


    > потоки передают сообщение, адресат (IP:PORT) и объект для
    > ответа (колбек функция, объект синхронизации (евент)) транспортному
    > потоку

    вот тут начинаются проблемы. Система плагиновая DLL, поэтому потоков от сторонних плагинов может быть сколько угодно, может быть они вызовут транспорт один раз, а может будут вызывать постоянно. Соответственно, или на каждый запрос каждый раз создавать объект синхронизации и потом его удалять, или на каждый ID потока создавать свой объект синхронизации, а при каждом запросе искать его в таблице - вопрос тогда, когда и кем финализировать объекты синхронизации.
    И нельзя ли сделать как-то оптимальнее.
  • Сергей М. © (30.01.09 19:33) [29]

    > Добежал   (30.01.09 17:34) [27]
    >
    >


    Да по барабану какая там "система")
    При чем тут какие-то там "плагины" ?

    LMD
  • Сергей М. © (30.01.09 19:35) [30]

    > Slym


    Ты это КОМУ ?
    "Добежавший" заранее занял "позу боевого чайника" - это видно невооруженным глазом)
  • Slym © (02.02.09 05:26) [31]
    Добежал   (30.01.09 17:54) [28]
    можно сразу в блокирующий метод обрамить код:


    ClientTable - поля (Event,IP,Port,Msg);
    TRec=record
    Event,IP,Port,Msg
    end;

    function Transport.Send(const Msg,IP:string;Port:word;TimeOut:longint):string;
    begin
     result:='';
     Event:=CreateEvent;
     try
       ClientTable.Add(Event,IP,Port);
       Socket.send(Msg,IP,Port);
       if WaitForSingleObject(Event,TimeOut)=OK then
         result:=ClientTable.GetMsg(Event);
     finally
       ClientTable.Remove(Event);
       CloseObject(Event);
     end;
     CloseHandle(Event);
    end;

    procedure OnSocket.Recv(RemoteIP,RemotePort,Data);
    var Record:TRec;
    begin
     if ClientTable.FindRecord(RemoteIP,RemotePort,var Record) then
     begin
       Record.Msg:=Data;
       SetEvent(Record.Event);
     endl
    end;

    procedure Thread.Execute
    begin
     while not Terminated do
     begin
       s:=Transport.send('Hello!','192.168.1.1',666,TimeOut);
       if length(s)<>0 then
        Writeln(s);
     end;
    end;


    Доступ к ClientTable и Socket должен быть заключен в критическую секцию
  • Slym © (02.02.09 05:28) [32]
    можно не постоянно креатить евенты а держать пул евентов
  • Добежал (02.02.09 10:32) [33]

    > можно не постоянно креатить евенты а держать пул евентов

    ну да, наверное так и сделаю. Спасибо!
  • Добежал (02.02.09 13:44) [34]
    А у Сергей М. очевидно начался "синдром борьбы с ламерами", ничего, в свое время даже Игоря Шевченко сия напасть не минула. Желаю, чтобы прошло также быстро.
  • Slym © (02.02.09 19:13) [35]
    Добежал   (02.02.09 10:32) [33]
    сделай "чтоб работало", оптимизировать потом будешь...
    время создания евента ничтожно по сравнению с временем убитым на грамотную организацию пула :)
  • Piter © (02.02.09 22:15) [36]
    Slym ©   (02.02.09 19:13) [35]
    сделай "чтоб работало", оптимизировать потом будешь...
    время создания евента ничтожно по сравнению с временем убитым на грамотную организацию пула :)


    Да я в общем переживаю не за время создания event'а, а за WaitForSingleObject. Если эвент занят, то поток уходит в режим ядра для засыпания, на это тратится немало тактов. С другой стороны, с современными процессорами это и не замечишь.

    Просто хочется сделать нормально и забыть о транспорте.
  • Сергей М. © (02.02.09 22:24) [37]

    > Piter ©   (02.02.09 22:15) [36]


    Ну и и что за буффонада с переодеваниями ?
  • Piter © (02.02.09 22:32) [38]
    Сергей М. ©   (02.02.09 22:24) [37]
    Ну и и что за буффонада с переодеваниями ?


    а что, у тебя ответы зависят от ника, задающего вопросы? Я лично тебе предлагаю над этим задуматься и решить - помогаешь ли ты людям или самоутверждаешься.
  • Сергей М. © (02.02.09 22:47) [39]
    Я тебе изложил свои соображения в [24], при  полном серьезе.
    А ты понес пургу про какие-то там плагины, которые вообще ни при чем ни с какого боку.
    Для этого нужна была клоунада, да ?
    Ну успехов тебе)
 
Конференция "Сети" » Отправка UDP по разным адресам через один сокет
Есть новые Нет новых   [134435   +33][b:0][p:0.001]