Форум программистов, компьютерный форум, киберфорум
Наши страницы

Delphi и сети

Войти
Регистрация
Восстановить пароль
 
 
artivad2
0 / 0 / 0
Регистрация: 09.06.2013
Сообщений: 29
#1

Чат на сокетах - Delphi

02.09.2016, 15:37. Просмотров 727. Ответов 30
Метки нет (Все метки)

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

Вот код:
Delphi
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ScktComp;
 
type
  TForm1 = class(TForm)
    ClientSocket: TClientSocket;
    ServerSocket: TServerSocket;
    portedit: TEdit;
    lblport: TLabel;
    IP: TLabel;
    Hostedit: TEdit;
    Nik: TLabel;
    NikEdit: TEdit;
    txtlbl: TLabel;
    TextEdit: TEdit;
    ChatMemo: TMemo;
    SendBtn: TButton;
    ServerBtn: TButton;
    ClientBtn: TButton;
 
    procedure FormCreate(Sender: TObject);
 
    procedure ServerBtnClick(Sender: TObject);
    procedure ServerSocketClientConnect(Sender: TObject;
    Socket: TCustomWinSocket);
    procedure ServerSocketClientDisconnect(Sender: TObject;
    Socket: TCustomWinSocket);
    procedure ServerSocketClientRead(Sender: TObject;
    Socket: TCustomWinSocket);
 
    procedure SendBtnClick(Sender: TObject);
    procedure ClientBtnClick(Sender: TObject);
    procedure ClientSocketRead(Sender: TObject;
    Socket: TCustomWinSocket);
    procedure ClientSocketConnect(Sender: TObject;
    Socket: TCustomWinSocket);
    procedure ClientSocketDisconnect(Sender: TObject;
    Socket: TCustomWinSocket);
    procedure ServerSocketAccept(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocketConnecting(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ServerSocketClientError(Sender: TObject;
      Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
      var ErrorCode: Integer);
 
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
 
//ЗАПОЛНЕНИЕ ПОЛЕЙ
procedure TForm1.FormCreate(Sender: TObject);
begin
PortEdit.Text:='50000';
HostEdit.Text:='192.168.0.100';
 
NikEdit.Clear;
TextEdit.Clear;
ChatMemo.Lines.Clear;
end;
 
 
//СЕРВЕР
procedure TForm1.ServerBtnClick(Sender: TObject);
begin
If ServerBtn.Tag=0 then
Begin
ClientBtn.Enabled:=False;
HostEdit.Enabled:=False;
PortEdit.Enabled:=False;
 
ServerSocket.Port:=StrToInt(PortEdit.Text);
ServerSocket.Active:=True;
ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Сервер создан');
ServerBtn.Tag:=1;
ServerBtn.Caption:='Закрыть сервер';
end
else
Begin
ClientBtn.Enabled:=True;
HostEdit.Enabled:=True;
PortEdit.Enabled:=True;
 
ServerSocket.Active:=False;
ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Сервер закрыт.');
ServerBtn.Tag:=0;
ServerBtn.Caption:='Создать сервер';
end;
end;
 
procedure TForm1.ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
begin
ChatMemo.Lines.Add(Socket.ReceiveText);
end;
 
procedure TForm1.ServerSocketClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Подключился клиент.');
end;
 
procedure TForm1.ServerSocketClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Клиент отключился.');
end;
 
procedure TForm1.ServerSocketAccept(Sender: TObject;
  Socket: TCustomWinSocket);
begin
 ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Подключился клиент.');
end;
 
procedure TForm1.ServerSocketClientError(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Ошибка.');
end;
 
 
 
//КЛИЕНТ
procedure TForm1.ClientBtnClick(Sender: TObject);
begin
If ClientBtn.Tag=0 then
Begin
 
ServerBtn.Enabled:=False;
HostEdit.Enabled:=False;
PortEdit.Enabled:=False;
 
ClientSocket.Port:=StrToInt(PortEdit.Text);
ClientSocket.Host:=HostEdit.Text;
ClientSocket.Address:=HostEdit.Text;
ClientSocket.Active:=True;
 
ClientBtn.Tag:=1;
ClientBtn.Caption:='Отключиться';
end
else
Begin
ServerBtn.Enabled:=True;
HostEdit.Enabled:=True;
PortEdit.Enabled:=True;
 
ClientSocket.Active:=False;
ClientBtn.Tag:=0;
ClientBtn.Caption:='Подключиться';
end;
end;
 
procedure TForm1.ClientSocketRead(Sender: TObject;
Socket: TCustomWinSocket);
begin
ChatMemo.Lines.Add(Socket.ReceiveText);
end;
 
procedure TForm1.ClientSocketConnecting(Sender: TObject;
  Socket: TCustomWinSocket);
begin
ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Подключение к серверу.');
end;
 
procedure TForm1.ClientSocketConnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Успешно.');
end;
 
procedure TForm1.ClientSocketDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Сеанс завершен.');
end;
 
 
 
//ОТПРАВКА СООБЩЕНИЯ
procedure TForm1.SendBtnClick(Sender: TObject);
begin
If ServerSocket.Active=True then
begin
ServerSocket.Socket.Connections[0].SendText('['+TimeToStr(Time)+'] '+NikEdit.Text+': '+TextEdit.Text+'');
end
else
begin
ClientSocket.Socket.SendText('['+TimeToStr(Time)+'] '+NikEdit.Text+': '+TextEdit.Text+'');
end;
ChatMemo.Lines.Add('['+TimeToStr(Time)+'] '+NikEdit.Text+': '+TextEdit.Text+'');
TextEdit.Text:='';
end;
 
end.
Предполагаю, что проблема кроется либо здесь:
Delphi
106
107
108
109
110
procedure TForm1.ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
begin
ChatMemo.Lines.Add(Socket.ReceiveText);
end;
либо тут:
Delphi
195
196
197
198
199
200
201
202
203
204
205
206
207
208
//ОТПРАВКА СООБЩЕНИЯ
procedure TForm1.SendBtnClick(Sender: TObject);
begin
If ServerSocket.Active=True then
begin
ServerSocket.Socket.Connections[0].SendText('['+TimeToStr(Time)+'] '+NikEdit.Text+': '+TextEdit.Text+'');
end
else
begin
ClientSocket.Socket.SendText('['+TimeToStr(Time)+'] '+NikEdit.Text+': '+TextEdit.Text+'');
end;
ChatMemo.Lines.Add('['+TimeToStr(Time)+'] '+NikEdit.Text+': '+TextEdit.Text+'');
TextEdit.Text:='';
end;
Ах да.. я тут новичок. Да и в программировании тоже тот еще ламер. Так что прошу сильно не ругать
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.09.2016, 15:37
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Чат на сокетах (Delphi):

Чат на сокетах - Delphi
Здравствуйте, форумчане. Сейчас занялся написанием чата на сокетах. Всё вроде бы хорошо, но уперся в 1 проблему. Когда один клиент...

Чат на сокетах (Нюанс) - Delphi
Здраствуйте. Сделал клиент,сервер на сокетах, на одном компе они работают- это понятно IP один и тот же. А можно ли сделать чтобы сервер...

Сделать чат на сокетах - Delphi
дал клиент другу(у меня сервер), мы используем одинаковый интернет от 1 провайдера. Программа не конектится.. На клиенте прописан мой ip...

Соединение на сокетах - Delphi
можно ли на сокетах созадть программу которая будет соединяться по интернету с другой своей копией? Ip серый

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

Регистрация/авторизация на сокетах - Delphi
Как с помощью компонентов TServerSocket и TClientSocket организовать регистрацию и авторизацию пользователей?

30
Fulcrum_013
699 / 764 / 74
Регистрация: 14.12.2014
Сообщений: 6,036
Завершенные тесты: 3
09.09.2016, 13:13 #16
Цитата Сообщение от artivad2 Посмотреть сообщение
Ась? Что для этого сделать?
Брекпоинт поставь. Ткни мышью в бордюр слева от кода чтобы там красный кружек появился. Потом запусти через F8 он на первой комаде остановится. Дальше через F9 запусти. Если управление доходит до точки останова он на ней остановится.
0
artivad2
0 / 0 / 0
Регистрация: 09.06.2013
Сообщений: 29
10.09.2016, 00:34  [ТС] #17
Fulcrum_013, Проверил. Галочка загорается. Приходит стало быть.
0
Fulcrum_013
699 / 764 / 74
Регистрация: 14.12.2014
Сообщений: 6,036
Завершенные тесты: 3
10.09.2016, 12:53 #18
Цитата Сообщение от artivad2 Посмотреть сообщение
Проверил. Галочка загорается. Приходит стало быть.
Теперь точно так же проверь вызывается ли TForm1.ClientSocketRead
0
artivad2
0 / 0 / 0
Регистрация: 09.06.2013
Сообщений: 29
10.09.2016, 17:54  [ТС] #19
Fulcrum_013, тоже выполняется.
Но клиент то читает, в этом дело. А сервер нет
0
Fulcrum_013
699 / 764 / 74
Регистрация: 14.12.2014
Сообщений: 6,036
Завершенные тесты: 3
10.09.2016, 18:00 #20
НУ тогда у сервера тоже ,брек-поинтом проверь приходит туда управление или нет
т.е. посавь бряк в ServerSocketClientRead;
Только похоже ошибка видна сразу:
Delphi
1
2
3
for X := 0 to ServerSocket.Socket.ActiveConnections-1 do
    ServerSocket.Socket.Connections[X].SendText(Socket.ReceiveText);
ChatMemo.Lines.Add(TimeToStr(Time)+' '+Socket.ReceiveText);
У тебя текст один раз пришел а прочитать ты его пытаешься ServerSocket.Socket.ActiveConnections+1 раз. При повторном чтении буфер пуст и сокет ждет пока в него что то не пришлют. Прочитай его в переменную а потом уже переменную рассылай и выводи. ReceiveText это не переменная (свойство), а функция, которая осуществляет чтение следующей строки из сокета.
0
artivad2
0 / 0 / 0
Регистрация: 09.06.2013
Сообщений: 29
10.09.2016, 18:13  [ТС] #21
В ServerSocketClientRead не работает, да
То есть до цикла дело вообще не доходит, вот в чем дело.
Ставил брейкпоинт на нём.

Добавлено через 5 минут
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
procedure TForm1.ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
X: Integer;
S: string;
begin
  S:=Socket.ReceiveText;
for X := 0 to ServerSocket.Socket.ActiveConnections-1 do
    ServerSocket.Socket.Connections[X].SendText(S);
 
ChatMemo.Lines.Add(TimeToStr(Time)+' '+S);
end;
Сделал так, та же шляпа..
Что с ним не так..
0
Fulcrum_013
699 / 764 / 74
Регистрация: 14.12.2014
Сообщений: 6,036
Завершенные тесты: 3
10.09.2016, 18:30 #22
Цитата Сообщение от artivad2 Посмотреть сообщение
То есть до цикла дело вообще не доходит, вот в чем дело.
Ну хоть ясно что не работает. Теперь будем искать почему.
строки "клиент подключился" пишет при подключении?
0
artivad2
0 / 0 / 0
Регистрация: 09.06.2013
Сообщений: 29
10.09.2016, 20:01  [ТС] #23
Fulcrum_013, да, в том то и дело
0
Fulcrum_013
699 / 764 / 74
Регистрация: 14.12.2014
Сообщений: 6,036
Завершенные тесты: 3
10.09.2016, 21:14 #24
Ану сделай вот так:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
procedure TForm1.SendBtnClick(Sender: TObject);
var 
  Text:string;
   X: Integer;
begin
Text:='['+TimeToStr(Time)+'] '+NikEdit.Text+': '+TextEdit.Text;
TextEdit.Text:='';
If ServerSocket.Active then
begin
  for X := 0 to ServerSocket.Socket.ActiveConnections-1 do
    ServerSocket.Socket.Connections[X].SendText(Text);
end
else 
if ClientSocket.Active then
begin
    ClientSocket.Socket.SendText(Text);
end
else
begin
    Text:="Socket Error"; 
end;
ChatMemo.Lines.Add(Text);
end;
Посмотри что будет говорит при отправке
1
artivad2
0 / 0 / 0
Регистрация: 09.06.2013
Сообщений: 29
11.09.2016, 03:14  [ТС] #25
Fulcrum_013, сделал. Так же.. Ну клиенту отправляется, а серверу нет, хотя в клиенте добавляется строка с текстом.
Выполняется именно второе условие, проверил это.
Скинуть проект?
0
Fulcrum_013
699 / 764 / 74
Регистрация: 14.12.2014
Сообщений: 6,036
Завершенные тесты: 3
11.09.2016, 10:10 #26
artivad2 Скидывай посмотрю,
0
artivad2
0 / 0 / 0
Регистрация: 09.06.2013
Сообщений: 29
11.09.2016, 16:39  [ТС] #27
вот
0
Вложения
Тип файла: rar program.rar (176.6 Кб, 7 просмотров)
Fulcrum_013
699 / 764 / 74
Регистрация: 14.12.2014
Сообщений: 6,036
Завершенные тесты: 3
11.09.2016, 16:56 #28
artivad2, В общем поменял у серверного сокета тип на stNonBloсking и все заработало
1
artivad2
0 / 0 / 0
Регистрация: 09.06.2013
Сообщений: 29
11.09.2016, 17:04  [ТС] #29
Fulcrum_013, ох.. черт. Что это за опция такая. Зачем..
Так и думал что дело не в коде. Совсем меня запутали.
Спасибо большое, дружище)

Добавлено через 3 минуты
Fulcrum_013, странно кстати, эта штука по умолчанию должна быть nonblocking как я посмотрел. Не помню чтоб менял там что-то..
0
Fulcrum_013
699 / 764 / 74
Регистрация: 14.12.2014
Сообщений: 6,036
Завершенные тесты: 3
11.09.2016, 17:09 #30
Цитата Сообщение от artivad2 Посмотреть сообщение
Что это за опция такая. Зачем..
Это переключатель синхронного и асинхронного режимов. В синхронном все живет на ручном опросе а не на событиях.
1
11.09.2016, 17:09
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.09.2016, 17:09
Привет! Вот еще темы с ответами:

Тестирование на сокетах. Можно ли как-то выделить вопрос-ответ в отдельную функцию? - Delphi
Хотелось бы узнать следующее... Есть сервер-сокет, и есть клиент-сокет. Если я на клиенте посылаю данные серверу и он отвечает, то...

Возможность отправки папки с файлами по локальной сети, сеть создана на сокетах - Delphi
Здравствуйте уважаемые форумчане, помогите пожалуйста, у меня есть программа, клиент - серверное приложение для тестирования знаний...

чат - Delphi
Здравствуйте форумчане и модераторы! У меня КП. Почти всё сделано правильно, но есть 1 но! У меня клиент не видит сервер и его...

Чат - Delphi
Привет всем Есть одна ява игра, в ней есть чат, хотелось бы написать свой чат т.е со своей программы смотреть сообщения в чате, но не...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru