на тему рефераты Информационно-образоательный портал
Рефераты, курсовые, дипломы, научные работы,
на тему рефераты
на тему рефераты
МЕНЮ|
на тему рефераты
поиск
Проектирование и разработка программы ЧАТ для локальной сети
p align="left">Вот переменные, которые понадобятся в программе:

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;

Опишем процедуру OnCreate формы:

procedure TForm1.FormCreate(Sender: TObject); begin // заголовок формы Caption:='Многопользовательский чат'; Application.Title:=Caption; // предложенное значения порта PortEdit.Text:=' Порт сервера'; // адрес при проверке программы на одном ПК ("сам на себя") HostEdit.Text:=' Адрес сервера '; // введем ник по-умолчанию, остальные поля просто очистим NikEdit.Text:='Ананим'; TextEdit.Clear; ChatMemo.Lines.Clear; end;

Процедурапрослушиванияоткрытых каналов сервером, выглядит так:procedure TForm1.ServerTimerTimer(Sender: TObject); begin // условие на наличие установленных каналов if ServerSocket.Socket.ActiveConnections<>0 then begin // цикл по существующим каналам for i:=1 to ServerSocket.Socket.ActiveConnections do begin // сохраним пакет (если ничего не прислали, по пакет пустой)

text:=ServerSocket.Socket.Connections.ReceiveText(); // условие, что пакет не пуст if text<>” then begin // получим код команды, длину строки com:=StrToInt(Copy(text,1,1)); len:=Length(text)-1; // определение команд case com of // код приема сообщения 0: begin // добавим в ChatMemo сообщение клиента ChatMemo.Lines.Add(Copy(text,2,len)); // разошлем сообщение пользователям (кроме того, кто прислал) for j:=0 to ServerSocket.Socket.ActiveConnections-1 do begin if (j+1)<>i then ServerSocket.Socket.Connections[j].SendText('0?+Copy(text,2,len)); end; end; // код приема ника клиента 1: begin // запишем в массив полученный ник UserMas.Name:=Copy(text,2,len); // отметим, что пользователь записан в список UserMas.Rec:=True; // обновляем список UpdateUserList; end; end; end; end; end; // разрешение на выполнение процедур обновления if UpdDo=True then begin // обновляем массив пользователей UpdateUserMas; // обновляем список пользователей UpdateUserList; // блокируем разрешение UpdDo:=False; end; end;

Перевод программы в режим сервера осуществляется клавишей “Создать сервер” (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

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;

UserListView.Items.Clear;

ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Сессия закрыта.');

ClientBtn.Tag:=0;

ClientBtn.Caption:='Подключиться';

end;

end;

procedure TForm1.ServerSocketClientConnect(Sender: TObject;

Socket: TCustomWinSocket);

begin

ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Подключился клиент.');

UpdDo:=True;

end;

procedure TForm1.ServerSocketClientDisconnect(Sender: TObject;

Socket: TCustomWinSocket);

begin

ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Клиент отключился.');

UpdDo:=True;

end;

procedure TForm1.SendBtnClick(Sender: TObject);

begin

If ServerSocket.Active=True then

For i:=0 to ServerSocket.Socket.ActiveConnections-1 do

ServerSocket.Socket.Connections[i].SendText('0['+TimeToStr(Time)+'] '+NikEdit.Text+': '+TextEdit.Text)

else

ClientSocket.Socket.SendText('0['+TimeToStr(Time)+'] '+NikEdit.Text+': '+TextEdit.Text);

ChatMemo.Lines.Add('['+TimeToStr(Time)+'] '+NikEdit.Text+': '+TextEdit.Text);

TextEdit.Clear;

end;

procedure TForm1.ClientSocketRead(Sender: TObject;

Socket: TCustomWinSocket);

begin

text:=Socket.ReceiveText();

com:=StrToInt(Copy(text,1,1));

len:=Length(text)-1;

Case com of

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

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;

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.ServerTimerTimer(Sender: TObject);

begin

If ServerSocket.Socket.ActiveConnections<>0 then

Begin

For i:=1 to ServerSocket.Socket.ActiveConnections do

Begin

text:=ServerSocket.Socket.Connections[i-1].ReceiveText();

If text<>'' then

Begin

com:=StrToInt(Copy(text,1,1));

len:=Length(text)-1;

Case com of

0: Begin

ChatMemo.Lines.Add(Copy(text,2,len));

For j:=0 to ServerSocket.Socket.ActiveConnections-1 do

Begin

If (j+1)<>i then ServerSocket.Socket.Connections[j].SendText('0'+Copy(text,2,len));

end;

end;

1: Begin

UserMas[i].Name:=Copy(text,2,len);

UserMas[i].Rec:=True;

UpdateUserList;

end;

end;

end;

end;

end;

If UpdDo=True then

Begin

UpdateUserMas;

UpdateUserList;

UpdDo:=False;

end;

end;

procedure TForm1.TextEditKeyDown(Sender: TObject; var Key: Word;

Shift: TShiftState);

begin

If Key=VK_RETURN then SendBtn.Click;

end;

end.

Заключение

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

В данный момент, в связи с бурным развитием WEB технологий, нет смысла создавать собственную программу чата. Так как в более удобно взять уже готовый, полностью завершенный чат.

Приложение

Запущенный сервер:

При подключение к серверу (у сервера):

При подключении к серверу (у клиента):

Отправка сообщений (у сервера и клиента):

Страницы: 1, 2



© 2003-2013
Рефераты бесплатно, курсовые, рефераты биология, большая бибилиотека рефератов, дипломы, научные работы, рефераты право, рефераты, рефераты скачать, рефераты литература, курсовые работы, реферат, доклады, рефераты медицина, рефераты на тему, сочинения, реферат бесплатно, рефераты авиация, рефераты психология, рефераты математика, рефераты кулинария, рефераты логистика, рефераты анатомия, рефераты маркетинг, рефераты релиния, рефераты социология, рефераты менеджемент.