Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.54/123: Рейтинг темы: голосов - 123, средняя оценка - 4.54
 Аватар для Maikl Til
12 / 12 / 1
Регистрация: 19.03.2010
Сообщений: 71

TCPClient && TCPServer Indy Components

24.06.2010, 22:54. Показов 25384. Ответов 51
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет.

Программа пишется в C++ Builder 2010.

Написал Серверную часть чата и Клиентскую часть чата. Естественно не все, что хотелось бы ^_^


Схема идеи:

Client 1-3 Посылают сообщения, которые попадают на сервер. После того как сервер получил сообщение, он записывает сообщение в лог и рассылает его всем Client'aм и тому кто его послал. Вот в принципе и вся идея. Помогите разобраться с этим

Проблема этих программ:
1) При отправке сообщения на сервер используя кириллические символы, сервер отображает символы кириллицы как : "?????????????".


Исходник: Client && Server.rar

Unit1.cpp
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
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "IdBaseComponent"
#pragma link "IdComponent"
#pragma link "IdContext"
#pragma link "IdCustomTCPServer"
#pragma link "IdTCPServer"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    LBT->Caption = "Сервер Отключен";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   int con = StrToInt(EConnect->Text);
    ChatServer->Active = false;
    ChatServer->Active = true;
    ChatServer->MaxConnections = con;
    Memo1->Lines->Add("Была нажата кнопка \"Refresh Server\"");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
    if (ChatServer->Active) {
    LBT->Caption = "Сервер Активен";
 }
 else {
     LBT->Caption = "Сервер Отключен";
 }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ChatServerExecute(TIdContext *AContext)
{
   int length = AContext->Connection->Socket->ReadLongInt();
   UnicodeString Message = AContext->Connection->Socket->ReadString(length);
   AContext->Connection->Disconnect();
   Memo1->Lines->Add(Message);
   LMessage->Items->Add(Message);
}
//---------------------------------------------------------------------------
Unit1.h

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
//---------------------------------------------------------------------------
 
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include "IdBaseComponent.hpp"
#include "IdComponent.hpp"
#include "IdContext.hpp"
#include "IdCustomTCPServer.hpp"
#include "IdTCPServer.hpp"
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
    TIdTCPServer *ChatServer;
    TButton *Button1;
    TEdit *EConnect;
    TLabel *Label1;
    TLabel *LBT;
    TTimer *Timer1;
    TMemo *Memo1;
    TListBox *LMessage;
    void __fastcall Button1Click(TObject *Sender);
    void __fastcall Timer1Timer(TObject *Sender);
    void __fastcall ChatServerExecute(TIdContext *AContext);
private:    // User declarations
public:     // User declarations
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif


Клиентская часть.

Unit3.cpp

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
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "Unit3.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "IdBaseComponent"
#pragma link "IdComponent"
#pragma link "IdTCPClient"
#pragma link "IdTCPConnection"
#pragma link "IdContext"
#pragma link "IdCustomTCPServer"
#pragma link "IdTCPServer"
#pragma resource "*.dfm"
TForm3 *Form3;
//---------------------------------------------------------------------------
__fastcall TForm3::TForm3(TComponent* Owner)
    : TForm(Owner)
{
 
  EHost->Enabled = false;
  EPort->Enabled = false;
  CheckBox1->Caption = "Ввести параметры";
}
//---------------------------------------------------------------------------
void __fastcall TForm3::CheckBox1Click(TObject *Sender)
{
if (CheckBox1->Checked) {
    EHost->Enabled = true;
    EPort->Enabled = true;
    EHost->Text = "";
    EPort->Text = "";
    CheckBox1->Caption = "Вернуть настройки";
}  else {
    EHost->Enabled = false;
    EPort->Enabled = false;
    EHost->Text = "192.168.0.102";
    EPort->Text = "6666";
    CheckBox1->Caption = "Ввести параметры";
}
}
//---------------------------------------------------------------------------
void __fastcall TForm3::Button1Click(TObject *Sender)
{
 
    ChatClient->Host = EHost->Text; // имя хоста
    ChatClient->Port = 6666;  // номер порта
    ChatClient->Connect();
 
    ChatClient->Socket->Write(EMessage->Text.Length());
    ChatClient->Socket->Write(EMessage->Text);
    ChatClient->Disconnect(); // прерываем соединение
}
//---------------------------------------------------------------------------
Unit3.h

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
//---------------------------------------------------------------------------
 
#ifndef Unit3H
#define Unit3H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include "IdBaseComponent.hpp"
#include "IdComponent.hpp"
#include "IdTCPClient.hpp"
#include "IdTCPConnection.hpp"
#include "IdContext.hpp"
#include "IdCustomTCPServer.hpp"
#include "IdTCPServer.hpp"
//---------------------------------------------------------------------------
class TForm3 : public TForm
{
__published:    // IDE-managed Components
    TEdit *EHost;
    TEdit *EPort;
    TGroupBox *GroupBox1;
    TListBox *LMessage;
    TEdit *EMessage;
    TButton *Button1;
    TGroupBox *GroupBox2;
    TCheckBox *CheckBox1;
    TIdTCPClient *ChatClient;
    void __fastcall CheckBox1Click(TObject *Sender);
    void __fastcall Button1Click(TObject *Sender);
private:    // User declarations
public:     // User declarations
    __fastcall TForm3(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm3 *Form3;
//---------------------------------------------------------------------------
#endif
1
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
24.06.2010, 22:54
Ответы с готовыми решениями:

Это что за иероглифы? if(!((a-4)&~7)&&!!(a-4))
Случайно наткнулся, выражение if(a&gt;=5 &amp; a&lt;=11) &quot;проще&quot; записывается так: if(!((a-4)&amp;~7)&amp;&amp;!!(a-4)) Фигасе проще, что они...

TCPServer и TCPClient
Помогите мне пожалуста разобратся с этими двумя компонентами. Я хочу сделать интернет чат.

Синхронизация TCPClient и TCPServer
Я работаю с C++Builder2006, если кто знает помогите разобраться: Клиент посылает серверу запрос и разрывает соединение. Сервер...

51
 Аватар для Dinkin
783 / 556 / 136
Регистрация: 31.05.2013
Сообщений: 3,145
Записей в блоге: 3
21.08.2015, 23:14
Студворк — интернет-сервис помощи студентам
так я Вам про че и говорю...раньше было,сейчас нет. Теперь через AContext
0
98 / 10 / 0
Регистрация: 21.02.2011
Сообщений: 474
22.08.2015, 01:05
А? Пояясните плиззз.. Вот я добавил компоненты. Откуда у этого Acontext ноги растут? Как юзать функции Indy компонентов потом? Это что за зверь?

Добавлено через 6 минут
А, вот начинаю въезжать
0
98 / 10 / 0
Регистрация: 21.02.2011
Сообщений: 474
29.08.2015, 02:32
А прием сообщений от сервера клиентом точно делать в "событии" OnConnected? Как вот тут? Или есть что-то другое?

C++
1
2
3
4
5
6
void __fastcall TForm3::ChatClientConnected(TObject *Sender)
{
  //---------------принимаем сообщение от сервера--------------------------->
  UnicodeString Message = ChatClient->IOHandler->ReadLn(enUTF8);
  LMessage->Items->Add(Message);
}
Спасибо за советы

Добавлено через 42 минуты
Еще один момент:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void __fastcall TForm1::Button3Click(TObject *Sender)
{
  if (Form1->Edit2->Text=="")
  {
    Form1->Edit2->Text="Write something please";
    Form1->Edit2->Color=clRed;
  }
  else
  {
    String SendT;
        SendT=Form1->Edit2->Text;
    if(Form1->CheckBox1->Checked)
    {
      Form1->IdTCPClient1->IOHandler->Write(SendT.Length());
      Form1->IdTCPClient1->IOHandler->Write(SendT);
    }
    else
    {
      Form1->IdTCPServer1->IOHandler->Write(SendT.Length());
      Form1->IdTCPServer1->IOHandler->Write(SendT);
    }
  }
}
В зависимости от того, есть галочка или нет приложение может быть либо клиентом либо сервером. При отправке сообщения можно либо IdTCPClient использовать, и это нормально работает, либо IdTCPServer. Но вот тут засада, так как:
[bcc64 Error] Unit1.cpp(99): no member named 'Write' in 'Idserveriohandler::TIdServerIOHandler' //Нет метода Write...
Вопрос о реализации приема таких посылок клиентом в силе.

Хороших всем выходных.
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
29.08.2015, 21:59
C++
1
2
3
4
5
6
7
8
void __fastcall TForm1::ChatServerExecute(TIdContext *AContext)
{
   int length = AContext->Connection->Socket->ReadLongInt();
   UnicodeString Message = AContext->Connection->Socket->ReadString(length);
   AContext->Connection->Disconnect();
   Memo1->Lines->Add(Message);
   LMessage->Items->Add(Message);
}
Я точно не помню, но если не ошибаюсь этот метод сервер вызывается из вторичного потока, а значит выводить так сообщения мемо нельзя(без синхронизации)
0
98 / 10 / 0
Регистрация: 21.02.2011
Сообщений: 474
02.09.2015, 00:39
Нет никакого Execute события на клиенте. Нельзя написать что то типа
C++
1
void __fastcall TForm1::ChatClientExecute(TIdContext *AContext)
Если сервер отправляет сообщение в виде:
C++
1
2
Form1->IdTCPServer1->IOHandler->Write(SendT.Length());
      Form1->IdTCPServer1->IOHandler->Write(SendT);
То как ее может принять клиент?

Добавлено через 22 часа 46 минут
Есть кто живой??
0
 Аватар для Dinkin
783 / 556 / 136
Регистрация: 31.05.2013
Сообщений: 3,145
Записей в блоге: 3
02.09.2015, 00:45
Вы путаете с обычными сокетами.
* В инди сервер может отправлять сообщения клиенту непосредствено только при ответе. Сам взять и отправить он не может.
* Клиент в инди может получать сообщения только при запросе. Он не может постоянно "сидеть и ждать", когда сервер решиться что то ответить. Запрос у клиента происходит только в момент конекта к серверу и отправке данных.
1
98 / 10 / 0
Регистрация: 21.02.2011
Сообщений: 474
02.09.2015, 01:42
Иными словами для полновесного общения между двумя экземплярами приложения каждый экземпляр должен иметь и клиентский и серверный компонент. Либо отправка ответа только при "подтверждении получения" так? Как сделать такой ответ сервера?
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
02.09.2015, 12:44
Цитата Сообщение от Dinkin Посмотреть сообщение
Вы путаете с обычными сокетами.
* В инди сервер может отправлять сообщения клиенту непосредствено только при ответе. Сам взять и отправить он не может.
* Клиент в инди может получать сообщения только при запросе. Он не может постоянно "сидеть и ждать", когда сервер решиться что то ответить. Запрос у клиента происходит только в момент конекта к серверу и отправке данных.
Иными словами нечто вроде полудупекса

Добавлено через 4 минуты
Цитата Сообщение от newline Посмотреть сообщение
Иными словами для полновесного общения между двумя экземплярами приложения каждый экземпляр должен иметь и клиентский и серверный компонент. Либо отправка ответа только при "подтверждении получения" так? Как сделать такой ответ сервера?
Думаю для начала стоит рассмотреть смену протокола на UDP допускающего бродкасты и имеющий немного другой способ общения, и возможно придется использовать что-то другое вместо Indy.
1
98 / 10 / 0
Регистрация: 21.02.2011
Сообщений: 474
02.09.2015, 18:52
Цитата Сообщение от Avazart Посмотреть сообщение
Думаю для начала стоит рассмотреть смену протокола на UDP допускающего бродкасты и имеющий немного другой способ общения, и возможно придется использовать что-то другое вместо Indy.
Про UDP и броадкаст - отправку всем /куда попало /дошло или нет ... Тоже есть у меня вопросы. До этой штуки я еще доберусь. День разберусь с полученной инфой а следующий шаг - UDP Спасибо вам за ваши советы.
0
98 / 10 / 0
Регистрация: 21.02.2011
Сообщений: 474
03.09.2015, 19:10
Спасибо вам за информацию. Сегодня буду разбираться дальше. Ясно что ответ посылка от сервера клиенту- только в виде ответа, после принятия данных. Вообщем то что мне и надо. Идеально. Получается для любого подключения - а их может быть много создается отдельный поток. Не перепутаешь.
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
03.09.2015, 19:19
Цитата Сообщение от newline Посмотреть сообщение
Получается для любого подключения - а их может быть много создается отдельный поток. Не перепутаешь.
Как я помню не отдельный поток, а поток из пула потоков.
0
98 / 10 / 0
Регистрация: 21.02.2011
Сообщений: 474
09.09.2015, 00:06
Вернулся с длительных трехдневных выходных. Продолжу ка я матчасть учить. Спасибо всем принимающим участие
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
09.09.2015, 00:06
Помогаю со студенческими работами здесь

Снова TCPServer и TCPClient
Пытаюсь сделать программку по этой статье,...

Передача файлов через TcpServer и TcpClient
Добрый день, уважаемые форумчане. Столкнулся я со следующей задачей. Мне необходимо передать файл с одного компьютера на другой, используя...

TcpServer и TcpClient, как переслать сообщение
Как работать с TcpServer и TcpClient в C++Builder 2010? Например, как переслать сообщение от клиента к серверу и обратно?

Оператор && - добавить в одну строчку Memo текст с ListBox1 и ListBox2
значит нужно добавить в одну строчку Memo текст с ListBox1 и ListBox2 хотел реализовать через оператор &quot;и&quot; &amp;&amp; но видает...

Rad studio XE3 && OpenGL
скачал отсюда библиотеки http://www.onlinedisk.ru/file/620466/ glut.dll and glut32.dll скопировал в windows/system32 glut.h и glaux.h...


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

Или воспользуйтесь поиском по форуму:
52
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru