Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Клуб программистов > Обсуждение статей
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.05.2011, 15:51   #621
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
Восклицание Небольшое замечание по работе чата

Я заметил уже давно, что лучше вместо приемной переменной text использовать другое имя, поскольку это зарезервировано и связано с Caption формы, ...т.е. при изменении содержимого переменной text, заголовок формы автоматически меняется. Переменную text нужно переименовать в nettext.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 23.05.2011, 16:23   #622
darek13
Пользователь
 
Аватар для darek13
 
Регистрация: 27.04.2011
Сообщений: 68
По умолчанию

когда сообщение шифруется то шифруется один текс и передается, но когда сервер принимает сообщение он принимает польностью строку с датой и ником, и так же с сообщением. И вот когда происходит разшифровка то получается что разшифровуется и дата и ник и сообщение и получаются бока, подскажи как отсечь лишнее и сделать так что бы разшифровывался один текст.
А по поводу переменной text то это понятно у меня уже давно все испраленно было )
darek13 вне форума Ответить с цитированием
Старый 23.05.2011, 18:01   #623
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Цитата:
Сообщение от darek13 Посмотреть сообщение
подскажи как отсечь лишнее и сделать так что бы разшифровывался один текст.
Можно ввести дополнительный байт в пакет перед частью самого текста. Т.е. будет: {ключ}+{дата}+{байт разделения}+{зашифрованный текст}. Пусть процедура расшифровки или строчки кода перед ней считает байты и как встретит байт разделения (символ, который нельзя ввести с клавиатуры) будет "знать", что все остальное после него - это зашифрованный текст, нужно скопировать эту часть до конца пакета.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 23.05.2011, 18:35   #624
darek13
Пользователь
 
Аватар для darek13
 
Регистрация: 27.04.2011
Сообщений: 68
По умолчанию

а показать пример ты бы не мог, словесно как бы все понятно, но вот реализовать что то не оч получается
darek13 вне форума Ответить с цитированием
Старый 23.05.2011, 19:53   #625
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Нет, код за тебя писать не буду , но подтолкну к его самостоятельному написанию подробным образом рассказав теорию.

Вот мы на стороне отправляющего сообщение клиента. Структура пакета уже описана: {ключ}+{дата}+{байт разделения}+{зашифрованный текст}. Пример? ...он есть в коде чата:

Код:
ClientSocket.Socket.SendText('0'+FontName+FontSize+FontColor+'['+TimeToStr(Time)+']  '+NikEdit.Text+':  '+TextEdit.Text);
Посмотрим, что тут у нас за структура пакета. Итак: '0'+FontName+FontSize+FontColor+'['+TimeToStr(Time)+'] '+NikEdit.Text+': '+TextEdit.Text или {ключ}+{шрифт}+{дата}+{ник}+{текст} . Ключ "0" - сообщение общего формата, "3" - приват. Это у меня так, у тебя может быть как-угодно, как составишь структуру. Шрифт - если не нужен,можешь выкинуть из кода везде. Дата - тут время создания сообщения, плюс скобочки квадратные, которые чисто декоративно отделяют его от остальной части сообщения. Ник - кто посылает сообщение. Текст - что пишет. Так вот, между датой и ником можно втиснуть один символ разделения, пусть Chr(140), каким образом? ...да так же через сложение.

Все, это понятно. Пакет ушел на сервер. Теперь нужно встречать другому клиенту, поскольку пакет через сервер идет транзитом без расшифровки. Смотрим стандартный прием:

Код:
procedure TForm1.ClientSocketRead(Sender: TObject;
  Socket: TCustomWinSocket);
begin

// получим текст, код комманды, длину строки
  nettext:=Socket.ReceiveText();
  com:=StrToInt(Copy(nettext,1,1));
  len:=Length(nettext)-1;
// определение комманд
  Case com of

// добавим в ChatRichEdit сообщение с сервера
    0: ShowColorMassage(nettext, 0);

// отошлем свой ник на сервер
    ...
// примем строку списка пользователей
    ...

// добавим в ChatRichEdit приватное сообщение с сервера
    3: ShowColorMassage(Copy(nettext,1,5)+Copy(nettext,7+Length(NikEdit.Text),len-Length(NikEdit.Text)-1), 1);
   end;

end;
Процедура ShowColorMassage - рукописная, ознакомься с ее работой в коде чата. Ты либо ее применяешь и внутри нее расшифровываешь текст, либо не используешь ее и пишешь расшифровку сюда же в case.

Мы помним, что в пакете есть байт (символ разделения), который нужно отыскать. Создаем цикл, от 1 до конца пакета. На каждом шаге сверяем очередной символ с Chr(140). Если будет истина, то копировать пакет с текущего символа+1 до конца пакета и приравнивать это строковой переменной, которая будет являться параметром к функции дешифровки. Следом сбрасываем цикл (break).

Все.

Можно вообще точно знать сколько байт в ключе пакета и шифровать все подряд вместе с датой, тогда байт разделения не нужен.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 26.05.2011, 14:45   #626
darek13
Пользователь
 
Аватар для darek13
 
Регистрация: 27.04.2011
Сообщений: 68
По умолчанию

Beermonza
Подскажи такую вещь, у когда отправляется сообщение всем пользователям с клиента, то происходит на сервере ошибка
"List index out bounsds (2), 2 - сколько пользователей подключенно, если 3 пользователя то будет (3), в чем это может быть прикол? И это тока при отсылки сообщений всем пользователям на клиенте, на личных все хорошо работает, как у клиента так и у сервера, и сервер нормально отсылает всем сообщение.
Да кстати и была переменная моменена где ты говорил i на b Поменять, но это ж в личных сообщения на сервере.
Буду очень признател за помощь
darek13 вне форума Ответить с цитированием
Старый 26.05.2011, 15:08   #627
darek13
Пользователь
 
Аватар для darek13
 
Регистрация: 27.04.2011
Сообщений: 68
По умолчанию

У меня то разделен сервер и клиент, так что предоставлю код, может где то ошибка допущена:

ServerTimerTimer

Код:
procedure TForm2.ServerTimerTimer(Sender: TObject);
begin
      // условие на наличие установленных каналов
  If SS2.Socket.ActiveConnections<>0 then
    Begin
// цикл по существующим каналам
      For i:=1 to SS2.Socket.ActiveConnections do
        Begin
// сохраним пакет (если ничего не прислали, по пакет пустой)
          txt:=SS2.Socket.Connections[i-1].ReceiveText();
// условие, что пакет не пуст
          If txt<>'' then
            Begin
// получим код комманды, длину строки
              com:=StrToInt(Copy(txt,1,1));
              len:=Length(txt)-1;
// определение комманд
              Case com of
// код приема сообщения --------------------------------------------------------
                0: Begin
// добавим в ChatRichEdit сообщение клиента
                     ShowColorMassage(txt, 0);
// разошлем сообщение пользователям (кроме того, кто прислал)
                     For j:=0 to ServerSocket.Socket.ActiveConnections-1 do
                       Begin
                         If (j+1)<>i then SS2.Socket.Connections[j].SendText(txt);
                       end;
                   end;
// -----------------------------------------------------------------------------
// код приема ника клиента -----------------------------------------------------
                1: Begin
// запишем в массив полученный ник
                     UserMas[i].Name:=Copy(txt,2,len);
// отметим, что пользователь записан в список
                     UserMas[i].Rec:=True;
// обновляем список
                     UpdateUserList;
                   end;
// -----------------------------------------------------------------------------
// код приема приватного сообщения ---------------------------------------------
                3: Begin
// укажем начальный символ
                     poss:=6;
// обнулим счетчик символов
                     x:=0;
// пробегаем по длине принятой строки
                     For j:=6 to len+1 do
                       Begin
// записываем в счетчик сдвиг
                         x:=x+1;
// если найден ключ (конец части ника в строке)
                         If Copy(txt,j,1)=Chr(152) then
                           Begin
// сохраняем ник приватного пользователя
                             PrivateUser:=Copy(txt,poss,x-1);
                           end;
                       end;
// если приватный пользователь - "сервер"
                     If PrivateUser=NikEdit.Text then
                       Begin
// добавим в ChatRichEdit сообщение клиента
                         ShowColorMassage(Copy(txt,1,5)+Copy(txt,7+Length(PrivateUser),len-Length(PrivateUser)-1), 1);
                       end
                     else
                       Begin
// создаем цикл перебора пользователей
                         For b:=0 to SS2.Socket.ActiveConnections-1 do
                           Begin
// если пользователь найден
                             If UserMas[b+1].Name=PrivateUser then
                               Begin
// отсылаем сообщение в канал приватного пользователя
                                 SS2.Socket.Connections[b].SendText(txt);
// сбрасываем цикл
                                 break;
                               end;
                           end;
                       end;
                   end;
// -----------------------------------------------------------------------------
               end;
            end;
        end;
    end;
// разрешение на выполнение процедур обновления
  If UpdDo=True then
    Begin
// обновляем массив пользователей
      UpdateUserMas;
// обновляем список пользователей
      UpdateUserList;
// блокируем разрешений
      UpdDo:=False;
    end;
end;
Фишка в том, что хоть и ошибка выскакивает сообщения доходит и отображается

А при открытом делфи выскакивает такое сообщение
" Project Server.exe rainsed exception class ElistError with message 'List index out of bounds (1)' Process stopped. Use Step or Run to continue. "

Последний раз редактировалось darek13; 26.05.2011 в 15:27.
darek13 вне форума Ответить с цитированием
Старый 26.05.2011, 15:22   #628
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

"List index out of bounds (2) - выход за пределы адреса, т.е. отсутствует указатель на второй канал в данном случае. Вот тут ошибка:

Код:
// код приема сообщения --------------------------------------------------------
                0: Begin
// добавим в ChatRichEdit сообщение клиента
                     ShowColorMassage(txt, 0);
// разошлем сообщение пользователям (кроме того, кто прислал)
                     For k:=0 to ServerSocket.Socket.ActiveConnections-1 do
                       Begin
                         If (k+1)<>i then SS2.Socket.Connections[k].SendText(txt);
                       end;
                   end;
// -----------------------------------------------------------------------------
Если серверный сокет носит имя SS2, то и цикл должен быть For k:=0 to SS2.Socket.ActiveConnections-1 do
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его

Последний раз редактировалось Beermonza; 26.05.2011 в 15:24.
Beermonza вне форума Ответить с цитированием
Старый 26.05.2011, 15:30   #629
darek13
Пользователь
 
Аватар для darek13
 
Регистрация: 27.04.2011
Сообщений: 68
По умолчанию

Спасибо большое, внатуре в это впроблема была, просто провтыкал переименовать в этом месте, а я уже час сижу и переменный перейменовал и код прогнал заново, респект тебе большой )))
darek13 вне форума Ответить с цитированием
Старый 28.05.2011, 01:06   #630
darek13
Пользователь
 
Аватар для darek13
 
Регистрация: 27.04.2011
Сообщений: 68
По умолчанию

Beermonza
а у тебя случайно нет исходников по делфи для передачи данных по сети как клиент-сервер, сервер - клиент и возможность клиент-клиент? буду очень признатель за любую помошь по этой теме
darek13 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
обновление в блоге - Создание клиент-сервера Pblog Обсуждение статей 0 03.10.2007 17:12
обновление в блоге - Диплом. Создание и продвижение сайта - готовь сани летом, а дипл Pblog Обсуждение статей 0 31.08.2007 20:00
обновление в блоге - USB Холодильник Pblog Обсуждение статей 0 25.06.2007 14:13
обновление в блоге - О ярлыках Pblog Обсуждение статей 0 27.05.2007 03:17