Форум программистов, компьютерный форум, киберфорум
PascalABC.NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.76/41: Рейтинг темы: голосов - 41, средняя оценка - 4.76
 Аватар для Syrax
28 / 19 / 16
Регистрация: 09.12.2009
Сообщений: 135

Клиент-серверное приложение: чат

09.01.2015, 04:54. Показов 8580. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Пытаюсь написать велосипед клиент-серверный чатик. Исходники брал где-то здесь, частично переписано с C# примера.
Прошу вот какой помощи: если к серверу подключаются два и более клиента, то сообщения, с клиентов отправленные, отправляются лишь клиенту №1. У остальных максимум появляются их же сообщения. У первого клиента также бывают проблемы с отображением сообщений один за одним и они собираются в большую кучу.

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

Сервер:
Кликните здесь для просмотра всего текста

Pascal
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
uses
  System, System.Net, System.Net.Sockets, System.IO, System.Threading, crt;
 
type
  TByteArray = array of byte;
 
var
  client: array [1..64] of TCPClient;
  s_str: array [1..64] of NetworkStream;
  s_raw: TByteArray;
  listener: system.Net.Sockets.TcpListener;
  s_ip, msg, nowdate, cl_str: string;
  s_port, length, i: integer;
  thr: array [1..64] of thread;
  thr_s: thread;
 
procedure chat(data: object);
var
  i, err:integer;
  name: string;
begin
  Val(data.ToString, i, err);
  s_str[i] := client[i].GetStream;
  length := s_str[i].Read(s_raw, 0, s_raw.Length);
  name := System.Text.Encoding.Default.GetString(s_raw, 0, length);
  writeln('Есть клиент ', name, '.');
  msg := Concat('Добро пожаловать на сервер ', s_ip, ', ', name, '!');
  s_str[i].Write(System.Text.Encoding.Default.GetBytes(msg), 0, msg.Length);
  try
    while true do 
    begin
      length := s_str[i].Read(s_raw, 0, s_raw.Length);
      cl_str := System.Text.Encoding.Default.GetString(s_raw, 0, length);
      writeln(name, ': ', cl_str);
      for j:integer:=1 to i do begin
        //s_str[j] := client[j].GetStream;
        msg := name + ': ' + cl_str{+#13#10};
        if s_str[j].CanWrite then
          s_str[j].Write(System.Text.Encoding.Default.GetBytes(msg), 0, msg.Length);
      end;
    end;
  except
    textcolor(4);
    writeln('Клиент отключился.');
    textcolor(2);
  end;
end;
 
 
begin
  s_raw := TByteArray(System.Array.CreateInstance(typeof(byte), 1024));
  try
    textcolor(14);
    write('Введите IP: ');
    readln(s_ip);
    write('Введите порт: ');
    readln(s_port);
    listener := TCPListener.Create(IPAddress.Parse(s_ip), s_port);
    listener.Start(64);
    textcolor(2);
    writeln('Готово. Ожидаем подключения...');
  except
    textcolor(4);
    writeln('Ошибка. Приложение будет закрыто.');
    sleep(2500);
    exit;
  end;
  i := 1;
  while true do
    if listener.Pending then
    begin
      client[i] := listener.AcceptTcpClient();
      thr[i] := new Thread(chat);
      thr[i].Start(i);
      i += 1;
    end;
end.


Клиент:
Кликните здесь для просмотра всего текста

Pascal
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
uses
  System, System.Net, System.Net.Sockets, System.IO, crt;
 
type
  TByteArray = array of byte;
 
var
  client: TCPClient;
  s_str: NetworkStream;
  s_raw: TByteArray;
  s_ip, cl_str, cl_stro, name: string;
  s_port, length: integer;
  
begin
  s_raw := TByteArray(System.Array.CreateInstance(typeof(byte), 1024));
  try
    textcolor(14);
    write('Введите IP: ');
    readln(s_ip);
    write('Введите порт: ');
    readln(s_port);
  except
    textcolor(4);
    writeln('Какая-то ошибка... Закрываем приложение.');
    sleep(2500);
    exit;
  end;
  textcolor(2);
  try
    client:=TCPClient.Create;
    client.Connect(ipAddress.Parse(s_ip), s_port);
    if client.Connected = true then
      begin
        write('Введите имя: '); readln(name);
        s_str:=client.GetStream;
        s_str.Write(System.Text.Encoding.Default.GetBytes(name), 0, name.Length);
        writeln('Подключено к ', s_ip);
        length:=s_str.Read(s_raw, 0, s_raw.Length);
        cl_str:=System.Text.Encoding.Default.GetString(s_raw, 0, length);
        writeln(cl_str);
        while true do
          begin
          {$omp parallel sections }
            begin
              begin
                length:=s_str.Read(s_raw, 0, s_raw.Length);
                cl_stro:=System.Text.Encoding.Default.GetString(s_raw, 0, length);
                writeln(cl_stro);
              end;
              begin
                readln(cl_str);
                s_str.Write(System.Text.Encoding.Default.GetBytes(cl_str), 0, cl_str.Length);
              end;
            end;
          end;
      end;
  except
    if client.Connected = false then
      begin
        textcolor(4);
        writeln('Подключение не удалось. Выход...');
        sleep(2500);
        exit;
      end;
  end;
end.


Добавлено через 1 час 27 минут
Небольшое изменение в "сервере" и теперь сообщения летят на все клиенты. Но проблема с несвоевременным показом сообщений осталась. Буду благодарен за помощь.

Кликните здесь для просмотра всего текста
Pascal
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
uses
  System, System.Net, System.Net.Sockets, System.IO, System.Threading, crt;
 
type
  TByteArray = array of byte;
 
var
  client: array [1..64] of TCPClient;
  s_str: array [1..64] of NetworkStream;
  s_raw: TByteArray;
  listener: system.Net.Sockets.TcpListener;
  s_ip, msg, nowdate, cl_str: string;
  s_port, length, i, n: integer;
  thr: array [1..64] of thread;
  thr_s: thread;
 
procedure chat(data: object);
var
  i, err:integer;
  name: string;
begin
  Val(data.ToString, i, err);
  s_str[i] := client[i].GetStream;
  length := s_str[i].Read(s_raw, 0, s_raw.Length);
  name := System.Text.Encoding.Default.GetString(s_raw, 0, length);
  writeln('Есть клиент ', name, '.');
  msg := Concat('Добро пожаловать на сервер ', s_ip, ', ', name, '!');
  s_str[i].Write(System.Text.Encoding.Default.GetBytes(msg), 0, msg.Length);
  try
    while true do 
    begin
      length := s_str[i].Read(s_raw, 0, s_raw.Length);
      cl_str := System.Text.Encoding.Default.GetString(s_raw, 0, length);
      writeln(name, ': ', cl_str);
      for j:integer:=1 to n do begin
        s_str[j] := client[j].GetStream;
        msg := name + ': ' + cl_str{+#13#10};
        if s_str[j].CanWrite then
          s_str[j].Write(System.Text.Encoding.Default.GetBytes(msg), 0, msg.Length)
        else
          writeln('Ошибка. Невозможно отправить сообщение клиенту.');
      end;
    end;
  except
    textcolor(4);
    writeln('Клиент отключился.');
    textcolor(2);
  end;
end;
 
 
begin
  s_raw := TByteArray(System.Array.CreateInstance(typeof(byte), 1024));
  try
    textcolor(14);
    write('Введите IP: ');
    readln(s_ip);
    write('Введите порт: ');
    readln(s_port);
    listener := TCPListener.Create(IPAddress.Parse(s_ip), s_port);
    listener.Start(64);
    textcolor(2);
    writeln('Готово. Ожидаем подключения...');
  except
    textcolor(4);
    writeln('Ошибка. Приложение будет закрыто.');
    sleep(2500);
    exit;
  end;
  i := 0;
  while true do
    if listener.Pending then
    begin
      i += 1;
      n:=i;
      client[i] := listener.AcceptTcpClient();
      thr[i] := new Thread(chat);
      thr[i].Start(i);
    end;
end.


Добавлено через 4 минуты
Pascal+C#+.Net = Чертова_Магия.
1
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
09.01.2015, 04:54
Ответы с готовыми решениями:

Клиент-серверное приложение для защищённой передачи файлов по сети
Нужно создать разработать программу на Паскале клиент-серверное приложение для защищённой передачи файлов по сети. Как это вообще возможно...

Клиент-серверное приложение (чат)
Пишу свой чат используючи TServerSocket и TClientSocket. У меня на компютере программа работает клиент соединяется с сервером но я скинул...

Клиент-серверное приложение (чат) и динамический IP адрес
Доброго времени суток... Много шарил в инете в поисках исходников да и литературы по поводу Клиент-серверных приложений(грубо говоря для...

7
 Аватар для Syrax
28 / 19 / 16
Регистрация: 09.12.2009
Сообщений: 135
11.01.2015, 14:52  [ТС]
Не знаю, зачем я пытался использовать OMP, но, переведя все на thread'ы, все заработало. Финальные версии клиента и сервера ниже.

Сервер.
Кликните здесь для просмотра всего текста
Pascal
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
uses
  System, System.Net, System.Net.Sockets, System.IO, System.Threading, crt;
 
type
  TByteArray = array of byte;
 
var
  client: array [1..64] of TCPClient;
  s_str: array [1..64] of NetworkStream;
  s_raw: TByteArray;
  listener: system.Net.Sockets.TcpListener;
  s_ip, msg, nowdate, cl_str: string;
  s_port, length, i, n: integer;
  thr: array [1..64] of thread;
  thr_s: thread;
 
procedure chat(data: object);
var
  i, err:integer;
  name: string;
begin
  Val(data.ToString, i, err);
  s_str[i] := client[i].GetStream;
  length := s_str[i].Read(s_raw, 0, s_raw.Length);
  name := System.Text.Encoding.Default.GetString(s_raw, 0, length);
  writeln('Есть клиент ', name, '.');
  msg := Concat('Добро пожаловать на сервер ', s_ip, ', ', name, '!');
  s_str[i].Write(System.Text.Encoding.Default.GetBytes(msg), 0, msg.Length);
  try
    while true do 
    begin
      length := s_str[i].Read(s_raw, 0, s_raw.Length);
      cl_str := System.Text.Encoding.Default.GetString(s_raw, 0, length);
      writeln(name, ': ', cl_str);
      for j:integer:=1 to n do begin
        s_str[j] := client[j].GetStream;
        msg := name + ': ' + cl_str{+#13#10};
        if s_str[j].CanWrite then
          s_str[j].Write(System.Text.Encoding.Default.GetBytes(msg), 0, msg.Length)
        else
          writeln('Ошибка. Невозможно отправить сообщение клиенту.');
      end;
    end;
  except
    textcolor(4);
    writeln('Клиент отключился.');
    textcolor(2);
  end;
end;
 
 
begin
  s_raw := TByteArray(System.Array.CreateInstance(typeof(byte), 1024));
  try
    textcolor(14);
    write('Введите IP: ');
    readln(s_ip);
    write('Введите порт: ');
    readln(s_port);
    listener := TCPListener.Create(IPAddress.Parse(s_ip), s_port);
    listener.Start(64);
    textcolor(2);
    writeln('Готово. Ожидаем подключения...');
  except
    textcolor(4);
    writeln('Ошибка. Приложение будет закрыто.');
    sleep(2500);
    exit;
  end;
  i := 0;
  while true do
    if listener.Pending then
    begin
      i += 1;
      n:=i;
      client[i] := listener.AcceptTcpClient();
      thr[i] := new Thread(chat);
      thr[i].Start(i);
    end;
end.


Клиент
Кликните здесь для просмотра всего текста
Pascal
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
uses
  System, System.Net, System.Net.Sockets, System.IO, System.Threading, crt;
 
type
  TByteArray = array of byte;
 
var
  client: TCPClient;
  s_str: NetworkStream;
  s_raw: TByteArray;
  s_ip, cl_str, cl_stro, name: string;
  s_port, length: integer;
  thr_s, thr_r: Thread;
 
procedure send;
begin
  while true do
  begin
    readln(cl_str);
    s_str.Write(System.Text.Encoding.Default.GetBytes(cl_str), 0, cl_str.Length);
  end;
end;
 
procedure read;
begin
  while true do
  begin
    length := s_str.Read(s_raw, 0, s_raw.Length);
    cl_stro := System.Text.Encoding.Default.GetString(s_raw, 0, length);
    writeln(cl_stro);
  end;
end;
 
begin
  s_raw := TByteArray(System.Array.CreateInstance(typeof(byte), 1024));
  try
    textcolor(14);
    write('Введите IP: ');
    readln(s_ip);
    write('Введите порт: ');
    readln(s_port);
  except
    textcolor(4);
    writeln('Какая-то ошибка... Закрываем приложение.');
    sleep(2500);
    exit;
  end;
  textcolor(2);
  try
    client := TCPClient.Create;
    client.Connect(ipAddress.Parse(s_ip), s_port);
    if client.Connected = true then
    begin
      write('Введите имя: '); readln(name);
      s_str := client.GetStream;
      s_str.Write(System.Text.Encoding.Default.GetBytes(name), 0, name.Length);
      writeln('Подключено к ', s_ip);
      length := s_str.Read(s_raw, 0, s_raw.Length);
      cl_str := System.Text.Encoding.Default.GetString(s_raw, 0, length);
      writeln(cl_str);
      thr_s := new Thread(send);
      thr_s.Start;
      thr_r := new Thread(read);
      thr_r.Start;
    end;
  except
    if client.Connected = false then
    begin
      textcolor(4);
      writeln('Подключение не удалось. Выход...');
      sleep(2500);
      exit;
    end;
  end;
end.


Всем большое спасибо! ^__^
5
0 / 0 / 0
Регистрация: 05.06.2018
Сообщений: 10
19.06.2018, 20:34
а IP и порт я где должен взять?
0
 Аватар для Syrax
28 / 19 / 16
Регистрация: 09.12.2009
Сообщений: 135
20.06.2018, 08:24  [ТС]
Цитата Сообщение от keikuethas Посмотреть сообщение
а IP и порт я где должен взять?
IP -- тот, который указан в свойствах подключения. Во вложении мой IP: 192.168.88.14
Ну а порт использовать любой свободный и открытый. Я обычно указывал 22, он для SSH, но у меня редко что на нем висит.
Миниатюры
Клиент-серверное приложение: чат  
0
0 / 0 / 0
Регистрация: 05.06.2018
Сообщений: 10
12.07.2018, 16:59
а общаться-то по нему как, если сообщения вводить нельзя?!?
0
 Аватар для Syrax
28 / 19 / 16
Регистрация: 09.12.2009
Сообщений: 135
12.07.2018, 19:15  [ТС]
Сообщения можно вводить только в клиенте. Запустите два клиента и один сервер, если хотите пообщаться.
0
Aimez-vous les baguettes?
193 / 26 / 27
Регистрация: 25.10.2017
Сообщений: 165
12.07.2018, 20:12
Не по теме (не знаю как поставить).

Сам великий Syrax, творитель "Клиент-серверное приложение: чат" жив?
0
13.07.2018, 07:15  [ТС]

Не по теме:

Кнопка оффтопа расположена слева от кнопки Ютуба.
Не знаю, Алекс, почему я великий, но я не умирал. -)

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
13.07.2018, 07:15
Помогаю со студенческими работами здесь

Клиент-серверное приложение "Чат"
Подскажите, пожалуйста. Как написать серверную часть Чата? Что должно туда входить?

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

Клиент-серверное приложение. Сервер - ПК, клиент - телефон (Android)
Здравствуйте, решил для обучения написать программу для выключения ПК с телефона, используя компонент TIdTCPServer. Подскажите, как...

Клиент-серверное приложение: как определить, что сервер/клиент не отвечает в течении определенного времени
Пишу клиент-серверное приложение. Использую TCPListener и TCPClient. Вопрос: как определить что сервер(клиент) не отвечает в течении...

Клиент-серверное приложение
Заинтересовался написанием клиент-серверных приложений, с чего начать? что написать? есть ли какая-либо литература (желательно электронная)...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru