2 / 2 / 3
Регистрация: 18.10.2014
Сообщений: 98
Записей в блоге: 1

Создание Чата для 2х и более пользователей

18.09.2015, 21:48. Показов 3377. Ответов 3
Метки нет (Все метки)

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

Я хочу изучить компоненты IdTCPServer и IdTCPClient и дабы разобраться с работой данных компонентов я решил создать чат для 2х и более пользователей.

Немного полазив на форумах я нашел много примеров создания чата на BuilderC++ 6 и RadStudio 2010, но на XE8 нашел только несколько "отрывков" кода для обмена сообщениями между клиентом и сервером.

Вот моя идея создания чата:

Есть Сервер (Всего 1) у сервера есть Ip и порт для подключения.
Есть Клиент уже с заданными портами для подключения к Серверу.

Я сделал 2 программы "Сервер" и "Клиент", все соединил , протестил, но Сервер не рассылает сообщения пользователям, или вернее так : принимает ПОЛНОЕ сообщение от клиента, добавляет к себе, НО отсылает это же сообщение неверно тоесть Какую ту часть он отсылает и при этом только Клиенту который его ему послал....

Как должны приниматься сообщения и рассылаться:

1) Клиент набирает сообщение и отправляет его на сервер .
2) Сервер считывает данные с сообщения (читает его) и рассылает это сообщение всем подключенным к нему пользователям.
3) Клиенты получают сообщение от сервера.

вот исходный код Сервера

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
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
 
UnicodeString Message;
 
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdTCPServer1Connect(TIdContext *AContext)
{
//TStringList *Mess = new TStringList();
AnsiString name;//При подключении пользователя принимаем его имя
name = AContext->Connection->IOHandler->ReadLn(enUTF8);// прием имени пользователя подключившегося к нам
RichEdit1->Lines->Add("К нам подключился новый пользователь : " + name);
RichEdit2->Lines->Add(name);// Добавления пользователя в Список Пользователей
//AContext->Connection->IOHandler->WriteLnRFC(Mess->Text,enUTF8);//Хотел сделать рассылку всем пользователям о новом подключении
//AContext->Connection->IOHandler->WriteLnRFC("К нам подключился новый пользователь : "+Mess->Strings[1],enUTF8);//Хотел сделать рассылку всем пользователям о новом подключении
//delete Mess;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdTCPServer1Execute(TIdContext *AContext)
{
TStringList *Mess = new TStringList();// Сюда приходит сообщение ОТ клиента
Mess->Add( AContext->Connection->IOHandler->ReadLn(enUTF8));//  читает сообщение
AContext->Connection->IOHandler->Write(Mess->Text);// Вот тут Я хочу это сообщение отправить Назад только всем пользователям
//AContext->Connection->IOHandler->WriteLnRFC(Mess->Text,enUTF8);
RichEdit1->Lines->Add(Mess->Text);// добавление сообщения в "лог" сервера
delete Mess;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdTCPServer1Disconnect(TIdContext *AContext)
{
RichEdit1->Lines->Add("От нас отключились");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
IdTCPServer1->Active=true; // запуск сервера
RichEdit1->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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
//---------------------------------------------------------------------------
 
#include <vcl.h>
#include <Time.h>
#pragma hdrstop
 
#include "Unit1.h"
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
 
TStringList *Mess = new TStringList();
TStringList *MessFromServer = new TStringList();
AnsiString t,text,ptext;
int ptext1;
 
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Label1Click(TObject *Sender)
{
Mess->Clear();
MessFromServer->Clear();
ptext=Edit1->Text;
 
if(Edit1->Text.IsEmpty())
{
    RichEdit1->SelAttributes->Size=10;
    RichEdit1->SelAttributes->Color=clRed;
    RichEdit1->Lines->Add("Вы не ввели сообщение");
 
}
else{
if(ptext1 == 1)
{
    RichEdit1->SelAttributes->Size=10;
    RichEdit1->SelAttributes->Color=clRed;
    RichEdit1->Lines->Add("Вы уже отправили такое сообщение");
}
else
{
    try
        {
            Mess->Add(Edit2->Text+" : " + DateToStr(Date()) + " " + Time()+"\r\n"+Edit1->Text+"\r\n\r\n");//Добавление сообщения пользователя
            if(!IdTCPClient1->Connected() ) IdTCPClient1->Connect(); // подключение к серверу (Если мы выполнили регистрацию Button1->Click();
            IdTCPClient1->IOHandler->WriteLnRFC(Mess->Text,enUTF8);//оправка на сервер
            MessFromServer->Add( IdTCPClient1->IOHandler->ReadLn(enUTF8) );// прием ЭТОГО же сообщения от сервера
            RichEdit1->Lines->Add(MessFromServer->Text);// вывод его на экран
        }
    __finally
        {
         //IdTCPClient1->Disconnect();
        }
/*
    RichEdit1->SelAttributes->Size=8;
    RichEdit1->SelAttributes->Color=clPurple;
    RichEdit1->Lines->Add(Edit2->Text+" : " + DateToStr(Date()) + " " + Time());
    RichEdit1->SelAttributes->Size=10;
    RichEdit1->SelAttributes->Color=clBlack;
    RichEdit1->Lines->Add(Edit1->Text);     //+"\r\n"
    t=Edit1->Text;
    Edit1->Clear();
*/
}
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Label2Click(TObject *Sender)
{
/*
int r=0,g=0,b=0;
srand(time(NULL));
r=rand()%255;
g=rand()%255;
b=rand()%255;
RichEdit2->SelAttributes->Color=RGB(r,g,b);
RichEdit2->Lines->Add(Edit2->Text);
Edit2->Clear();
*/
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Edit1Change(TObject *Sender)
{
 
if(Edit1->Text == ptext)
    ptext1=1;
else
    ptext1=0;
 
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString newnwme;
AnsiString snewnwme;
 
IdTCPClient1->Host="188.242.240.30";
IdTCPClient1->Port= 80;
 
 
if(!Edit2->Text.IsEmpty())
{
    Label1->Enabled=true;
    Edit1->Enabled=true;
    Edit2->Enabled=false;
    try
    {
        newnwme = Edit2->Text;//Добавляем имя пользователя в newnwme
        if(!IdTCPClient1->Connected() ) IdTCPClient1->Connect();
        IdTCPClient1->IOHandler->WriteLnRFC(newnwme,enUTF8);//отправляем имя пользователя на сервер
        snewnwme>Add(IdTCPClient1->IOHandler->ReadLn(enUTF8));//Хотел принимать сообщение о занесении пользователя в список на сервере Но что то пошло не так и я убрал этот кусок кода
        RichEdit2->Lines->Add(newnwme);
    }
    __finally
    {
         //IdTCPClient1->Disconnect();
    }
}
else ShowMessage("Введите ваше имя");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdUDPClient1Connected(TObject *Sender)
{
RichEdit1->Lines->Add("Клиент присоединился к серверу");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdTCPClient1Connected(TObject *Sender)
{
RichEdit1->Lines->Add("Клиент подключен к серверу");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdTCPClient1Disconnected(TObject *Sender)
{
RichEdit1->Lines->Add("Связь с сервером прервана");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdTCPClient1Work(TObject *ASender, TWorkMode AWorkMode, __int64 AWorkCount)
{
//Тут я думал что если клиент работает то можно отловить и принимать все сообщения исходящие от сервера
TStringList *Mess2 = new TStringList();
Mess2->Add(IdTCPClient1->IOHandler->ReadLn(enUTF8));
RichEdit2->Lines->Add(Mess2->Text);
delete Mess2;
}
//---------------------------------------------------------------------------
Итак у меня вот такие проблемы и не знаю как их решить:

1) Сервер неправильно принимает сообщения (зачем то делает перенос строк)..
2) Сервер не рассылает сообщения всем подключенным пользователям...

P.S по интернету работает, клиент коннектиться к серверу

Прикрепил иллюстрации и исходники...

Если не сложно помогите или дайте совет как решить такую ситуацию или литературу для XE8..
Миниатюры
Создание Чата для 2х и более пользователей   Создание Чата для 2х и более пользователей   Создание Чата для 2х и более пользователей  

Вложения
Тип файла: rar Client.rar (3.69 Мб, 39 просмотров)
Тип файла: rar SERVER.rar (62.9 Кб, 40 просмотров)
1
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
18.09.2015, 21:48
Ответы с готовыми решениями:

Чат для 3 и более пользователей
Как можно организовать рассылку сообщений сразу двоим пользователям? Как создать некую сеть из троих (или более) человек? Например, есть...

Создание чата для локальной сети
Создаю сайт для локальной сети на основе ClientSocket и ServerSocket. Запускаю сервер. Запускаю клиент1, указываю IP-адрес сервера....

Доступ Для Одного И Более Пользователей
Люди добрые помогите! Есть задача чтобы пользователь нажал на кнопку выпало окошко с списком пользователей- от туда выбрали определенные...

3
 Аватар для AlexSt
61 / 60 / 9
Регистрация: 13.01.2009
Сообщений: 322
23.09.2015, 15:58
C
1
AContext->Connection->IOHandler->Write(Mess->Text);
Вот на эту строку внимание обрати. IOHandler я так понял это идентификатор потока ввода вывода для пользователя. соответсвенно тебе нужно использовать для каждого юзера свой IOHandler.
На сокетах писал, там было Socket1->Connections[сдесь ИД сессии]->WriteLn(Message);
Как то так если не ошибаюсь
Дома буду гляну
0
2 / 2 / 3
Регистрация: 18.10.2014
Сообщений: 98
Записей в блоге: 1
23.09.2015, 16:49  [ТС]
AlexSt, Буду признателен если поможете с этим, а то я так и оставил пока что проект в таком виде.
В Builder 6 там как то проще... а тут и толком найти ничего не могу
0
 Аватар для AlexSt
61 / 60 / 9
Регистрация: 13.01.2009
Сообщений: 322
24.09.2015, 11:30
C++
1
2
3
4
5
6
7
8
9
10
11
void __fastcall TForm1::TCPServer1Execute(TIdContext *AContext)
{
 
TStringList *Mess = new TStringList();
TList *list = new TList();
list = TCPServer1->Contexts->LockList();
Mess->Add( AContext->Connection->IOHandler->ReadLn(enUTF8));
for (int i = 0; i < list->Count; i++) {
TIdContext *Thread = (TIdContext*) list->Items[i];
Thread->Connection->IOHandler->Write(Mess->Text);
}
Как то так броадкаст мессага.

Добавлено через 31 минуту
C++
1
2
TCPServer1->Contexts->UnlockList();
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
24.09.2015, 11:30
Помогаю со студенческими работами здесь

Создание p2p чата для частной локальной сети
Добрый день. Задача: Существует необходимость создать p2p час для нескольких клиентов внутри часной сети (без выхода в интернет). В...

Как сделать загрузку изображений для пользователей более удобной
В настоящий момент на сайте пользователи могут загружать свои статьи с помощью плагина USP (User Submitted Posts). При добавлении...

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

Вывод пользователей чата в список
Доброго времени суток! Пишу приложение на подобии аськи и необходимо организовать такой же список пользователей как и там. ...

Создание страницы для заявки от пользователей!
Решил сделать страницу заполнения форм как тут http://www.nn4you.ru/road/?app=true А вот код кнопки ОТПРАВИТЬ не знаю Задача: При...


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

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru