скачать рефераты
  RSS    

Меню

Быстрый поиск

скачать рефераты

скачать рефератыКурсовая работа: Проектирование и разработка программы ЧАТ для локальной сети

Далее идут события, которые должны происходить при определенном состоянии 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


Новости

Быстрый поиск

Группа вКонтакте: новости

Пока нет

Новости в Twitter и Facebook

  скачать рефераты              скачать рефераты

Новости

скачать рефераты

Обратная связь

Поиск
Обратная связь
Реклама и размещение статей на сайте
© 2010.