Jump to content

    
Sign in to follow this  
_sda

Работа с портами в протоколе UDP на делфи

Recommended Posts

Уважаемые,есть наша программа на ПК и некий внешний блок, который выполняет множество измерений. Связь с ним осуществляется с помощью Ethernet по протоколу UDP. Для этого я использую компонент TIdUDPServer. Блок имеет свой IP и на него отправляются управляющие команды, используя порт 4660. Через этот же порт блок на ПК отправляет массивы данных.Всё работает как часы.
Но вот заказчик изменил протокол обмена. Теперь программа должна отправлять команды через тот же порт 4660, а принимать разные массивы через разные порты:
Массив1 через порт 4661;
Массив2 через порт 4662;
Массив3 через порт 4663;
Массив4 через порт 4664.
Причём, должна быть предусмотрена возможность переключения на возврат к обычному обмену через один порт 4660.

Это выглядит примерно так: в блок отправляется команда, блок её декодирует и отсылает ответ с данными. В зависимости от кода команды ответ отсылается блоком на один из четырёх портов.
Как это реализовать, используя TIdUDPServer, я совершенно не понимаю.
Очень прошу помочь, хотя бы теоретически.

Share this post


Link to post
Share on other sites
5 minutes ago, _sda said:

Спасибо! А нет какого примера?

Уже лет 10 как делфи нет.

Пример - Ваша программа. Добавбте 4 TId... и будет счастье.

Share this post


Link to post
Share on other sites
6 hours ago, x893 said:

Сделать 5 UDP серверов

4660 - 4664

Сильная ж мысль. 
Как бы для того кто не знает Indy вполне логичная.
Однако Indy  компоненты блокирующие. И 5-ть серверов просто брошеных из палитры на форму работать не будут. 

Share this post


Link to post
Share on other sites
56 minutes ago, AlexandrY said:

Сильная ж мысль. 
Как бы для того кто не знает Indy вполне логичная.
Однако Indy  компоненты блокирующие. И 5-ть серверов просто брошеных из палитры на форму работать не будут. 

Значит надо использовать другой способ из 100500.

Share this post


Link to post
Share on other sites
7 часов назад, x893 сказал:

Значит надо использовать другой способ из 100500.

Спасибо!Отличный совет,главное конкретный.:biggrin:

8 часов назад, AlexandrY сказал:

Сильная ж мысль. 
Как бы для того кто не знает Indy вполне логичная.
Однако Indy  компоненты блокирующие. И 5-ть серверов просто брошеных из палитры на форму работать не будут. 

А что бы вы посоветовали? Забыл уточнить что сейчас программа - клиент(она шлёт запросы), а блок сервер.

Share this post


Link to post
Share on other sites

Если использовать 5 компонентов TIDUDPserver, каждый имеет свой порт,  но перед использованием одного конкретного деактивировать остальные. При этом блок остаётся как сервер, а программа как клиент. Данные принимать на активный компонент. Получится?

Share this post


Link to post
Share on other sites
4 hours ago, _sda said:

А что бы вы посоветовали? Забыл уточнить что сейчас программа - клиент(она шлёт запросы), а блок сервер.

Если прога клиент, то это облегчает только тем, что не надо задавать правила локальноу файрволу.

На языке Delphi я некторое время  не практикую, но на C++ в VCL для каждого UDP соедиения я делаю класс наследующий от специального интерфейса чтобы организовать независимый поток для UDP компонента.
Объявление выглядит так:

class TUDP_audio_server : public TCppInterfacedObject<TProc>
{
  public:
    _di_ITask                          itask;
    bool                               terminate_task;
    TCriticalSection                  *p_lock;
    uint8_t                            selected_mic;
    __property uint32_t lost_data_cnt =  {read = Getlost_data_cnt, write = Setlost_data_cnt};
    __property uint32_t data_read     =  {read = Getdata_read, write = Setdata_read};
    __fastcall TUDP_audio_server(HSTREAM astream, TFileStream  *fstrm, T_udp_serv_init_params *pinit);
    __fastcall ~TUDP_audio_server(void);
    void        __fastcall Terminate_task(void);
    void        __fastcall GetAudioDataBlock(int16_t *block, uint32_t sz, uint32_t *actual_sz);
  private:
    void        __fastcall Invoke(void);
    void        __fastcall UDPRead(TIdUDPListenerThread *AThread, const TIdBytes AData, TIdSocketHandle *ABinding);
    void        __fastcall Setlost_data_cnt(uint32_t val);
    uint32_t    __fastcall Getlost_data_cnt(void);
    void        __fastcall Setdata_read(uint32_t val);
    uint32_t    __fastcall Getdata_read(void);
    TLightweightEvent    *evt;
    TSpinLock            spinlock;
    uint32_t             data_read_val;
    uint32_t             lost_data_cnt_val;
    T_recv_audio_buf     rbuf;
    uint32_t             skipped_packet_cnt;
    HSTREAM              audio_stream;
    TFileStream         *filestream;
    uint16_t             sending_port;
    uint16_t             listening_port;
  protected:
    TIdUDPServer *udp_server;
};

 Реализация выглядит громоздко и с кучей зависимостей, поэтому сюда не вываливаю.

Словом задача недетская. 

 

Share this post


Link to post
Share on other sites

Спасибо! Только не уверен поможет ли это нашему программисту...

Я общаюсь с программистом из Австралии, говорит что задача пустяковая, только,редиска, не раскрывает ничего.

Share this post


Link to post
Share on other sites

Проблема не в этом - нет нормального программиста в штате. В нашем регионе это проблема. Уже второго эксплуатируем(у одного С у второго Делфи), у обоих среда разработки с нулевых годов.

Перебиваемся с шабашниками, а какой с них спрос? Либо так, либо никак.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this