48355 (Проектирование и разработка программы ЧАТ для локальной сети), страница 2
Описание файла
Документ из архива "Проектирование и разработка программы ЧАТ для локальной сети", который расположен в категории "". Всё это находится в предмете "информатика" из 1 семестр, которые можно найти в файловом архиве . Не смотря на прямую связь этого архива с , его также можно найти и в других разделах. Архив можно найти в разделе "курсовые/домашние работы", в предмете "информатика, программирование" в общих файлах.
Онлайн просмотр документа "48355"
Текст 2 страницы из документа "48355"
Перевод программы в режим сервера осуществляется клавишей “Создать сервер” (ServerBtn). Вот так выглядит процедура на нажатие клавиши ServerBtn (OnClick):
procedure TForm1.ServerBtnClick(Sender: TObject); begin if ServerBtn.Tag=0 then begin // клавишу ClientBtn и поля HostEdit, PortEdit, NikEdit заблокируем ClientBtn.Enabled:=False; HostEdit.Enabled:=False; PortEdit.Enabled:=False; NikEdit.Enabled:=False; // запишем указанный порт в ServerSocket ServerSocket.Port:=StrToInt(PortEdit.Text); // запускаем сервер ServerSocket.Active:=True; // добавим в ChatMemo сообщение с временем создания ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Сервер создан.’); // изменяем тэг ServerBtn.Tag:=1; // меняем надпись клавиши ServerBtn.Caption:=’Закрыть сервер’; // включаем таймер сервера ServerTimer.Enabled:=True; // вписываем параметры сервера UserMas[0].Status:=1; UserMas[0].Rec:=True; UserMas[0].Name:=NikEdit.Text; UserMas[0].Image:=1; // разрешаем обновление UpdDo:=True; end else begin // выключаем таймер сервера ServerTimer.Enabled:=False; // стираем параметры сервера UserMas[0].Status:=0; UserMas[0].Rec:=False; UserMas[0].Name:=’Неизвестный’; UserMas[0].Image:=0; // разрешаем обновление UpdDo:=True; // очищаем список клиентов UserListView.Items.Clear; // клавишу ClientBtn и поля HostEdit, PortEdit, NikEdit разблокируем ClientBtn.Enabled:=True; HostEdit.Enabled:=True; PortEdit.Enabled:=True; NikEdit.Enabled:=True; // закрываем сервер ServerSocket.Active:=False; // выводим сообщение в ChatMemo ChatMemo.Lines.Add(’['+TimeToStr(Time)+'] Сервер закрыт.’); // возвращаем тэгу исходное значение ServerBtn.Tag:=0; // возвращаем исходную надпись клавиши ServerBtn.Caption:=’Создать сервер’; end; end;
Далее идут события, которые должны происходить при определенном состоянии ServerSocket’а. Напишем процедуру, когда клиент подсоединился к серверу (OnClientConnect):
procedure TForm1.ServerSocketClientConnect(Sender: TObject; Socket: TCustomWinSocket); begin // добавим в ChatMemo сообщение с временем подключения клиента ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Подключился клиент.’); // разрешаем обновление UpdDo:=True; end;
Напишем процедуру, когда клиент отключается (OnClientDisconnect):
procedure TForm1.ServerSocketClientDisconnect(Sender: TObject; Socket: TCustomWinSocket); begin // добавим в ChatMemo сообщение с временем отключения клиента ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Клиент отключился.’); // разрешаем обновление UpdDo:=True; end;
Отправка сообщений. Она осуществляется нажатием клавиши “Отправить” (SendBtn), но необходима проверка режима программы сервер или клиент. Напишем ее процедуру (OnClick):
procedure TForm1.SendBtnClick(Sender: TObject); begin // проверка, в каком режиме находится программа if ServerSocket.Active=True then // отправляем сообщение с сервера всем пользователям for i:=0 to ServerSocket.Socket.ActiveConnections-1 do ServerSocket.Socket.Connections.SendText(’0['+TimeToStr(Time)+'] ‘+NikEdit.Text+’: ‘+TextEdit.Text) else // отправляем сообщение с клиента ClientSocket.Socket.SendText(’0['+TimeToStr(Time)+'] ‘+NikEdit.Text+’: ‘+TextEdit.Text); // отобразим сообщение в ChatMemo ChatMemo.Lines.Add(’['+TimeToStr(Time)+'] ‘+NikEdit.Text+’: ‘+TextEdit.Text); // очищаем TextEdit TextEdit.Clear; end;
Режим клиента. При нажатии клавиши “Подключиться” (ClientBtn), блокируется ServerBtn и активируется ClientSocket. Вот процедура ClientBtn (OnClick):
procedure TForm1.ClientBtnClick(Sender: TObject); begin if ClientBtn.Tag=0 then begin // клавишу ServerBtn и поля HostEdit, PortEdit заблокируем ServerBtn.Enabled:=False; HostEdit.Enabled:=False; PortEdit.Enabled:=False; // запишем указанный порт в ClientSocket ClientSocket.Port:=StrToInt(PortEdit.Text); // запишем хост и адрес (одно значение HostEdit в оба) ClientSocket.Host:=HostEdit.Text; ClientSocket.Address:=HostEdit.Text; // запускаем клиента ClientSocket.Active:=True; // изменяем тэг ClientBtn.Tag:=1; // меняем надпись клавиши ClientBtn.Caption:='Отключиться'; end else begin // клавишу ServerBtn и поля HostEdit, PortEdit разблокируем ServerBtn.Enabled:=True; HostEdit.Enabled:=True; PortEdit.Enabled:=True; // закрываем клиента ClientSocket.Active:=False; // очищаем список клиентов UserListView.Items.Clear; // выводим сообщение в ChatMemo ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Сессия закрыта.’); // возвращаем тэгу исходное значение ClientBtn.Tag:=0; // возвращаем исходную надпись клавиши ClientBtn.Caption:=’Подключиться’; end; end;
Процедуры на OnConnect, OnDisconnect, OnRead клиента ClientSocket. Сначала на чтение сообщения с сервера (OnRead):
procedure TForm1.ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket); begin // получим текст, код комманды, длину строки text:=Socket.ReceiveText(); com:=StrToInt(Copy(text,1,1)); len:=Length(text)-1; // определение комманд case com of // добавим в ChatMemo сообщение с сервера 0: ChatMemo.Lines.Add(Copy(text,2,len)); // отошлем свой ник на сервер 1: ClientSocket.Socket.SendText('1'+NikEdit.Text); // примем строку списка пользователей 2: begin // очищаем список клиентов UserListView.Items.Clear; // добавим ключ конца строки (т.к. вырезка символов с задержкой) text:=text+Chr(152); // укажем начальный символ pos:=2; // обнулим счетчик символов x:=0; // пробегаем по длине строки списка for j:=2 to len+1 do begin // записываем в счетчик сдвиг x:=x+1; // если найден ключ (отделение ников в строке) if Copy(text,j,1)=Chr(152) then begin // добавим в UserListView строку UItems:=UserListView.Items.Add; UItems.Caption:=Copy(text,pos,x-1); // укажем соответствующую иконку пользователя if pos>2 then UItems.ImageIndex:=0 else UItems.ImageIndex:=1; // изменим текущую позицию в строке списка pos:=j+1; // обнулим счетчик символов x:=0; end; end; end; end; end;
Дальше обычное добавление в ChatMemo определенного сообщения:
procedure TForm1.ClientSocketConnect(Sender: TObject; Socket: TCustomWinSocket); begin // добавим в ChatMemo сообщение о соединении с сервером ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Подключение к серверу.’); end;
procedure TForm1.ClientSocketDisconnect(Sender: TObject; Socket: TCustomWinSocket); begin // добавим в ChatMemo сообщение о потере связи ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Сервер не найден.’); end;
Хранителем информации о пользователях у нас выступает массив, процедура его заполнения и обновления выглядит так:
procedure TForm1.UpdateUserMas; begin // очищаем массив с информацией for i:=1 to 255 do begin UserMas.Status:=0; UserMas.Rec:=False; UserMas.Name:=’Неизвестный’; UserMas.Image:=0; end; // заполняем данные пользователей if ServerSocket.Socket.ActiveConnections<>0 then begin for i:=1 to ServerSocket.Socket.ActiveConnections do begin UserMas.Status:=2; UserMas.Name:=’Неизвестный’; UserMas.Image:=0; // запрашиваем имя (ник) пользователя по его каналу (код команды - 1) ServerSocket.Socket.Connections.SendText(’1′); end; end; end;
Список UserListView обновляется в следующей процедуре:
procedure TForm1.UpdateUserList; begin // очищаем список клиентов UserListView.Items.Clear; // очищаем переменную StrUserList:=''; // обнуляем пометку записи ContList:=0; // пробегаем по диапазону каналов for i:=0 to 255 do begin // если запись не пустая if UserMas.Status<>0 then begin // добавим в UserListView строку UItems:=UserListView.Items.Add; UItems.Caption:=UserMas.Name; UItems.ImageIndex:=UserMas.Image; // если пользователь не записан if UserMas.Rec=False then ContList:=1; // составляем строку пользователей StrUserList:=StrUserList+UserMas.Name+Chr(152); end; end; // если все пользователи отметились, и есть хоть один канал if (ContList=0) and (ServerSocket.Socket.ActiveConnections<>0) then begin // пробегаем по всем открытым каналам for i:=0 to ServerSocket.Socket.ActiveConnections-1 do begin // отправим строку списка пользователей (код команды - 2) ServerSocket.Socket.Connections.SendText(’2′+StrUserList); end; end; end;
Листинг программы
unit MainUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ScktComp, ExtCtrls, ImgList, ComCtrls, jpeg;
type
TForm1 = class(TForm)
ServerSocket: TServerSocket;
ClientSocket: TClientSocket;
PortEdit: TEdit;
NikEdit: TEdit;
TextEdit: TEdit;
ChatMemo: TMemo;
HostEdit: TEdit;
ServerBtn: TButton;
ClientBtn: TButton;
SendBtn: TButton;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
UserListView: TListView;
Label6: TLabel;
ImageList: TImageList;
ServerTimer: TTimer;
Image1: TImage;
procedure FormCreate(Sender: TObject);
procedure UpdateUserList;
procedure UpdateUserMas;
procedure ServerBtnClick(Sender: TObject);
procedure ClientBtnClick(Sender: TObject);
procedure ServerSocketClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocketClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure SendBtnClick(Sender: TObject);
procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);
procedure ClientSocketDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocketConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerTimerTimer(Sender: TObject);
procedure TextEditKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
private
{ Private declarations }
public
{ Public declarations }
end;
Type
TUserList = object
Status: Byte;
Rec: Boolean;
Name: String;
Image: Byte;
end;
var
Form1: TForm1;
i, j, com, ContList: Byte;
len, pos, x: Word;
text, StrUserList: String;
UpdDo: Boolean;
Buf: array[0..3] of Byte;
UserMas: array[0..255] of TUserList;
UItems: TListItem;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
Caption:='Многопользовательский чат';
Application.Title:=Caption;
PortEdit.Text:='Порт сервера';
HostEdit.Text:='Адрес сервера';
NikEdit.Text:='Ананим';
TextEdit.Clear;
ChatMemo.Lines.Clear;
end;
procedure TForm1.UpdateUserList;
begin
UserListView.Items.Clear;
StrUserList:='';
ContList:=0;
For i:=0 to 255 do
Begin
If UserMas[i].Status<>0 then
Begin
UItems:=UserListView.Items.Add;
UItems.Caption:=UserMas[i].Name;
UItems.ImageIndex:=UserMas[i].Image;
If UserMas[i].Rec=False then ContList:=1;
StrUserList:=StrUserList+UserMas[i].Name+Chr(152);
end;
end;
If (ContList=0) And (ServerSocket.Socket.ActiveConnections<>0) then
Begin
For i:=0 to ServerSocket.Socket.ActiveConnections-1 do
Begin
ServerSocket.Socket.Connections[i].SendText('2'+StrUserList);
end;
end;
end;
procedure TForm1.UpdateUserMas;
begin
For i:=1 to 255 do
Begin
UserMas[i].Status:=0;
UserMas[i].Rec:=False;
UserMas[i].Name:='Неизвестный';
UserMas[i].Image:=0;
end;
If ServerSocket.Socket.ActiveConnections<>0 then
Begin
For i:=1 to ServerSocket.Socket.ActiveConnections do
Begin
UserMas[i].Status:=2;
UserMas[i].Name:='Неизвестный';
UserMas[i].Image:=0;
ServerSocket.Socket.Connections[i-1].SendText('1');
end;
end;
end;
procedure TForm1.ServerBtnClick(Sender: TObject);
begin
If ServerBtn.Tag=0 then
Begin
ClientBtn.Enabled:=False;
HostEdit.Enabled:=False;
PortEdit.Enabled:=False;
NikEdit.Enabled:=False;
ServerSocket.Port:=StrToInt(PortEdit.Text);
ServerSocket.Active:=True;
ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Сервер создан.');
ServerBtn.Tag:=1;
ServerBtn.Caption:='Закрыть сервер';
ServerTimer.Enabled:=True;
UserMas[0].Status:=1;
UserMas[0].Rec:=True;
UserMas[0].Name:=NikEdit.Text;
UserMas[0].Image:=1;
UpdDo:=True;
end
else
Begin
ServerTimer.Enabled:=False;
UserMas[0].Status:=0;
UserMas[0].Rec:=False;
UserMas[0].Name:='Неизвестный';
UserMas[0].Image:=0;
UpdDo:=True;
UserListView.Items.Clear;
ClientBtn.Enabled:=True;
HostEdit.Enabled:=True;
PortEdit.Enabled:=True;
NikEdit.Enabled:=True;
ServerSocket.Active:=False;
ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Сервер закрыт.');
ServerBtn.Tag:=0;
ServerBtn.Caption:='Создать сервер';
end;
end;
procedure TForm1.ClientBtnClick(Sender: TObject);
begin
If ClientBtn.Tag=0 then