приложении (естественно, сообщения и реакция на них отличны от серверных).
Листинг 11.24.
Обработка строки, полученной от сервера
procedure ProcessMessage (strMessage: string);
var
strAction: string; //Тип сообщения (префикс сообщения)
len: Integer; //Длина строки strAction
begin
//Определим тип сообщения и выполним соответствующие действия
len := Pos(':', strMessage);
strAction := Copy (strMessage,1,len-1);
Delete(strMessage,1,len);
if (strAction = 'ok') then
begin
//Регистрация пользователя завершена – можно отправлять
//сообщения
Connect;
end
else if (strAction = 'error') then
begin
//Ошибка!!!
frmClient.TCPClient.Disconnect;
Disconnect;
MessageDlg(strMessage, mtError, [mbOK], 0);
end
else if (strAction = 'adduser') then
begin
//К разговору присоединился новый пользователь
frmClient.lstUsers.Items.Add (strMessage);
end
else if (strAction = 'deluser') then
begin
//Какой-то пользователь отсоединился
frmClient.lstUsers.Items.Delete(
frmClient.lstUsers.Items.IndexOf (strMessage));
end
else begin
//Покажем принятое сообщение
frmClient.txtChat.Lines.Add (strMessage);
end;
end;
Далее приводятся обработки событий, на которых, собственно, и основана работа клиентской программы. Обработчик нажатия кнопки cmbConnect, приведенный в листинге 11.25, пытается присоединиться к серверу. Если клиент присоединен к серверу, то эта же кнопка используется для его отсоединения.
Листинг 11.25.
Присоединение/отсоединение от сервера
procedure TfrmClient.cmbConnectClick(Sender: TObject);
begin
if (cmbConnect.Caption = 'Подключиться ') then
begin
//Проверим, чтобы были введены имя сервера
//и имя пользователя
if (txtServer.Text = '')then
begin
MessageDlg('Введите имя сервера в текстовое поле.',
mtInformation, [mbOK], 0);
Exit;
end
else if (txtUser.Text = '')then
begin
MessageDlg('Введите имя пользователя в текстовое поле. ',
mtInformation, [mbOK], 0);
Exit;
end;
//Пытаемся подключиться к серверу
try
TCPClient.Host := txtServer.Text;
TCPClient.Connect;
except
MessageDlg('Не удается соединиться с сервером',mtError,
[mbOK], 0);
end;
end
else
//Отключаемся от сервера
TCPClient.Disconnect;
end;
Обработчик нажатия кнопки cmbSend (листинг 11.26) отправляет сообщение, которое могут прочесть все пользователи, присоединенные к серверу.
Листинг 11.26.
Отправка сообщения всем собеседникам
procedure TfrmClient.cmbSendClick (Sender: TObject);
begin
if (txtMessage.Text <> '') then
begin
//Отправка сообщения всем собеседникам
TCPClient.WriteLn('text:' + txtMessage.Text);
txtMessage.Text := '
txtMessage.SetFocus;
end;
end;
При двойном щелчке кнопкой мыши на имени в списке пользователей отправляется сообщение, которое получает только выделенный в списке пользователь (листинг 11.27).
Листинг 11.27.
Отправка сообщения заданному собеседнику
procedure TfrmClient.lstUsersDblClick(Sender: TObject);
begin
if ((lstUsers.ItemIndex >= 0) and (txtMessage.Text <> ''))
then
begin
//Отправим сообщение только для выбранного собеседника
//(сообщение вида «имя_собеседника:текст_сообщения»)
TCPClient.WriteLn(lstUsers.Items.Strings[lstUsers.ItemIndex] +
':' + txtMessage.Text);
txtMessage.SetFocus;
end;
end;
Сразу после соединения с сервером, тоесть в обработчикеTfrmClient. TCPClient-Connected, приведенном в листинге 11.28, клиентская программа отправляет имя пользователя серверу. При отсоединении от сервера (тот же листинг 11.28) происходит соответствующее оформление внешнего вида формы frmClient.
Листинг 11.28.
Обработка присоединения/отсоединения от сервера
procedure TfrmClient.TCPClientConnected(Sender: TObject);
begin
//Отправляем на сервер имя пользователя
TCPClient.WriteLn('name:' + txtUser.Text);
end;
procedure TfrmClient.TCPClientDisconnected(Sender: TObject);
begin
//Оформим форму для отсоединенного от сервера состояния
Disconnect;
end;
Ключевой обработчик (именно по таймеру проверяется факт прихода сообщения от сервера) приведен в листинге 11.29. Для элемента управления TCPClient значение тайм-аута установлено для того, чтобы при отсутствии принятых данных клиентская программа не переходила надолго в состояние ожидания, а генерировалось исключение, по которому и можно судить, что данных еще нет (см. блок try в этом обработчике).
Листинг 11.29.
Проверка, есть ли данные от сервера
procedure TfrmClient.Timer1Timer (Sender: TObject);
var strMessage: string;
begin
//Проверим, нет ли для нас сообщения
if (TCPClient.Connected)then
begin
try
strMessage := TCPClient.ReadLn;
if (strMessage <> '')then
ProcessMessage (strMessage);
except
on EIdReadTimeout do ; //Ошибки тайм-аута игнорируем
else
//При остальных ошибках отсоединяемся от сервера
TCPClient.Disconnect;
end;
end;
end;
end.
Примечание
Чтобы при запуске клиентского приложения из среды Delphi постоянно не появлялись сообщения об исключениях (возникают при истечении тайм-аута в TfrmClient.TimeiiTimer), снимите флажок Stop on Delphi Exceptions на вкладке Language Exceptions диалогового окна Debugger Options (меню Tools → Debugger Options).
На этом рассмотрение сетевого взаимодействия средствами Delphi в рамках этой книги завершается. Конечно, в главе перечислены далеко не все типы соединений и служб, поддерживаемых хотя бы компонентами, поставляемыми вместе с Delphi. Для рассмотрения работы со всеми имеющимися компонентами понадобилось бы написать целую книгу. Тем не менее хочется надеяться, что приведенные в главе примеры помогут вам в освоении механизмов программного взаимодействия между частями компьютерной сети.
Глава 12 Шифрование
• Основы криптографии
• Шифр простой подстановки
• Транспозиция
• Шифр Виженера и его варианты
• Шифр с автоключом
• Взлом
По той или иной причине часто бывает необходимо сообщить определенную информацию конкретному кругу людей так, чтобы она оставалась тайной для других. Возникает вполне очевидный вопрос: что для этого нужно сделать? Скорее всего, многие читатели в разные моменты времени и с различными целями пытались решить для себя задачу о секретной передаче. В результате выбиралось приемлемое решение, наверняка повторяющее изобретение одного из существующих способов скрытой передачи информации, история которого насчитывает не одну тысячу лет.
В отношении задачи о секретной передаче нетрудно прийти к выводу, что есть три способа ее реализации в компьютерных системах:
• создание абсолютно надежного канала связи, к которому есть доступ только у отправителя и адресата;
• использование общедоступного канала связи, но скрытие самого факта передачи информации;
• использование общедоступного канала связи с передачей по нему нужной информации, определенным образом преобразованной так, что восстановить ее может только адресат.
Что касается первого способа, то при современном уровне развития науки и техники сделать такой канал связи между удаленными абонентами для неоднократной передачи больших объемов информации практически нереально.
Второй способ является предметом изучения стеганографии. В область этой науки