Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.80/82: Рейтинг темы: голосов - 82, средняя оценка - 4.80
98 / 10 / 0
Регистрация: 21.02.2011
Сообщений: 474

Indy Client/Server Обмен сообщениями

05.12.2012, 15:37. Показов 17231. Ответов 24

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

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

ВАЖНО Сервер отправляет ответ клиенту приславшему запрос.

Вот кособокий вариант клиента:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
Void __fastcall TForm1::Button1Click(TObject *Sender)
{
    Form1->IdTCPClient1->Host=Form1->Edit1->Text;     //Данные сервера
    Form1->IdTCPClient1->Port=StrToInt(Edit2->Text);
    try
    {
        IdTCPClient1->Disconnect();
        IdTCPClient1->Connect();
    }
    catch(...)
    {
        ShowMessage("Не удалось подключиться к серверу!");
    }
 
 
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
 try
    {
        IdTCPClient1->Connect("localhost");
    }
    catch(...)
    {
        ShowMessage("Не удалось подключиться к серверу!");
    }
 
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::Button2Click(TObject *Sender)
{
if(IdTCPClient1->Connected())
    {
        String mesg=Edit1->Text, recvmsg="r";
        IdTCPClient1->IOHandler->Write(mesg.Length());
        IdTCPClient1->IOHandler->Write(mesg);
        Memo1->Lines->Add("Отправлено: "+recvmsg);
        int length = IdTCPClient1->IOHandler->ReadLongInt();
        recvmsg = IdTCPClient1->IOHandler->ReadString(length);
        Memo1->Lines->Add("Ответ: "+recvmsg);
    }
    else
    {
        ShowMessage("Нет соединения с сервером!");
    }
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
  IdTCPClient1->Disconnect();
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::IdTCPClient1Connected(TObject *Sender)
{
  Memo1->Lines->Add("Клиент подключен к серверу");
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::IdTCPClient1Disconnected(TObject *Sender)
{
  Memo1->Lines->Add("Связь с сервером прервана");
А вот не менее кособокий сервер:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdTCPServer1Connect(TIdContext *AContext)
{
  Form1->Memo1->Lines->Add("К нам подключились");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdTCPServer1Execute(TIdContext *AContext)
{
    UnicodeString Message, ip, port;
    ////////////
    int length = AContext->Connection->IOHandler->ReadLongInt();
    Message = AContext->Connection->IOHandler->ReadString(length);
    Memo1->Lines->Add("------------------------------");
    Memo1->Lines->Add(Message);
    ip = AContext->Binding->PeerIP;                             //ОБЯЗАТЕЛЬНО запоминаем IP и
    port = AContext->Binding->PeerPort;                        // Порт клиента чтобы ответ ему заслать
    Memo1->Lines->Add(ip+":"+port);
    Memo1->Lines->Add("------------------------------");
    Sleep(500);
    Message = Message+" Сообщение получено";
    AContext->Connection->IOHandler->Write(Message.Length());
    AContext->Connection->IOHandler->Write(Message);
 
 
  /*      Такая была попытка
 
  Form1->Memo1->Lines->Add("К нам подключились");
  UnicodeString ReceivedLine;
  ReceivedLine = AContext->Connection->IOHandler->ReadLn(enUTF8);
  Form1->Memo1->Lines->Add(ReceivedLine);
  Form1->IdTCPClient1->IOHandler->WriteLn(Form1->Edit2->Text,enUTF8);;
  AContext->Connection->Disconnect();
  Form1->Memo1->Lines->Add("Отключение");      */
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdTCPServer1Disconnect(TIdContext *AContext)
{
  Form1->Memo1->Lines->Add("От нас отключились");
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 
  UnicodeString Message;
  Message=Form1->Edit1->Text;
  Message = Message + " Сообщение от сервера";
 // Form1->IdTCPServer1->IOHandler->A Write(Message.Length());
 // AContext->Connection->IOHandler->Write(Message);
 // Тут с отправкой по нажатию кнопки вообще не понял идеи
// Тем не менее сервер должен сам слать сообщения одному из клиентов по нажатию кнопки
}
Помогите разобраться с этой задачей. Облазил все - информации и INDY по теме - кот наплакал.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
05.12.2012, 15:37
Ответы с готовыми решениями:

INDY Server/Client Отправка данных с сервера клиенту C++
Нужно отправить константу с Сервера. Клиент должен принять константу и отобразить её в Listbox. На данный момент Передаются сообщения...

Indy client
Здравствуйте, пишу на c++. кто-нибудь может разобраться с Indy Clients в BorlandC++6 перерыл гугл никакой документации для c++ нет....

Indy Client
Подскажите как в indy client 10 c копейками версия родной из 10 билдера, данные из буфера сокета получать тут же. Я делал следующим...

24
98 / 10 / 0
Регистрация: 21.02.2011
Сообщений: 474
14.12.2012, 16:51  [ТС]
Студворк — интернет-сервис помощи студентам
Иными словами каждый программный модуль имеет компоненты ADOServer и ADOClient
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
14.12.2012, 16:56
Цитата Сообщение от newline Посмотреть сообщение
Иными словами каждый программный модуль имеет компоненты ADOServer и ADOClient
Ну а собственно как это меняет задачу ?
0
98 / 10 / 0
Регистрация: 21.02.2011
Сообщений: 474
14.12.2012, 17:00  [ТС]
Логика такая:
1. Сервер что-то там получил с модема и ADOClient этот мессадж шлет на клиент, где он принимается ADOServer-ом
2. Обратно наоборот.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
14.12.2012, 17:03
Ну говорю же через клиент еще один клиент реализовать...

Либо по запросу клиентов отсылать им обновления если они появились.
0
98 / 10 / 0
Регистрация: 21.02.2011
Сообщений: 474
17.12.2012, 15:36  [ТС]
И снова здравствуйте!
Переделал взаимодействие так:
Серверная часть программы:
C++
1
2
3
4
5
6
7
8
oid __fastcall TForm13::FormCreate(TObject *Sender)
{                                 //Запуск сервера. 
  Form13->IdTCPServer1->Active=false;
  Form13->IdTCPServer1->Active=true;
  Form13->Memo1->Lines->Add("Сервер активен");
 
  Form13->Timer1->Enabled=True;            //Таймер на запуск клиента
//клиент в серверной части нужен для передачи сообщения
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//Запуск "клиента" по таймеру
void __fastcall TForm13::Timer1Timer(TObject *Sender)
{
  Form13->Timer1->Enabled=False;
  if (Form13->IdTCPServer1->Active == false)
  {
    Form13->Button1->Enabled=true;
  }
  try
  {
   if (!Form13->IdTCPClient1->Connected() )
   {
     Form13->IdTCPClient1->Connect();
   }
  }
  __finally
  {
 
  }
}
Вот обработка события, для передачи сообщения в функцию обрабатывающую IdTCPServer1Execute
C++
1
2
3
4
5
6
void __fastcall TForm13::Edit1Change(TObject *Sender)
{
  EditChanged=True;
  String sen=Form13->Edit1->Text;
  Form13->IdTCPClient1->IOHandler->WriteLnRFC(sen, enUTF8);
}
А вот и сама эта функция:
C++
1
2
3
4
5
6
7
8
9
10
void __fastcall TForm13::IdTCPServer1Execute(TIdContext *AContext)
{
  if (first==0)
  {
    AContext->Connection->IOHandler->WriteLnRFC("Сервер ответил" ,enUTF8);
  }
  first=1;
  Form13->Memo1->Lines->Add(Form13->Edit1->Text);
  String received=Form13->Edit1->Text;
  AContext->Connection->IOHandler->WriteLnRFC("Сервер ответил "+received,enUTF8);
Задача прежняя. Мне надо организовать взаимодействие по следующему принципу:
1. Сервер рассылает некоторое сообщение ВСЕМ клиентам. Это происходит при изменении компонента EDIT1 (см выше)
2. Все подключенные клиенты это сообщение получают.
3. Один из подключенных клиентов отправляет запрос ("например подробности)". Запрос отправляется по нажатию на кнопку на клиенте.
4. Получив запрос, сервер отвечает именно тому клиенту который отправил запрос.

//Пояснения:
1. На сервере есть "локальный клиент" -IDTCPClient (INDY компонент). Он засылает в функцию
C++
1
void __fastcall TForm13::IdTCPServer1Execute(TIdContext *AContext)
строку которую и надо передать всем клиентам.
2. Получив сообщение в теле функции для обработки событий TCPServer-а, сервер должен разослать сообщение всем подключенным клиентам
C++
1
Context->Connection->IOHandler->WriteLnRFC("Сервер ответил "+received,enUTF8);
вот так.
3. Сервер ждет сообщения от какого-нибудь клиента, чтобы потом отправить ему ответ.
Помогите реализовать такое взаимодействие. Очень прошу. Я тут уже кажется все перепробовал...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
17.12.2012, 15:36

Обмен мгновенными сообщениями
Здравствуйте. Выручите пожалуйста. Сервер хранит список клиентов, связи между ними, а также осуществляет маршрутизацию сообщений. Клиент...

Недопустимый дескриптор окна. (Обмен сообщениями: TCP)
Доброго времени суток. Есть программа, которая производит обмен сообщениями по сети между несколькими компьютерами (использую TCP...

indy FTP server demo
Подскажите где можно скачать demo FTP server и клиент на Indy 9 под C++ builder. 6, на оффициальном сайте нашел только для делфи.

Server(Client)Socket
Всем привет. Собираюсь сделать передачу команд между сервером-клиентом через socket'ы, но возник один вопрос: будут ли проблемы с...

Client и Server Socket
Доброго дня суток , подскажите как можно переслать , к примеру , с клиента на сервер 2 переменные , я знаю только как можно одну: void...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
25
Ответ Создать тему
Новые блоги и статьи
Особенности gif сгенерированных в Си
russiannick 21.10.2026
Рассмотрим генерацию gif файлов, которые в Си имеют свои особенности. Gif представляет собой графический формат популярный в интернете. Посмотрим на палитру. Gif файл сгенерированный в си отличается. . .
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/ TL DR Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru