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

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

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

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 11.09.2008, 21:45   #61
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Ну, можно и так, хотя если используется процедура ShowColorMassage({текст},{индекс}), то достаточно написать так:

Код:
text:=Socket.ReceiveText();
ShowColorMassage(text,0);
...если клиент правильно сформировал заголовок, то цвет и стиль текста выведется автоматически.
Если же у вас нет специальной процедуры, тогда перед каждым выводом сообщения, нужно прописать параметры шрифта и присвоить текст в текущую ячейку:

Код:
ChatRichEdit.SelAttributes.Name
ChatRichEdit.SelAttributes.Size
ChatRichEdit.SelAttributes.Color
ChatRichEdit.SelAttributes.Style
ChatRichEdit.SelText
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 22.11.2008, 14:28   #62
ToBad
 
Регистрация: 20.12.2007
Сообщений: 3
По умолчанию Проблема при многочисленных подключениях

Здравствуйте !
Большое спасибо за Ваш проект и предоставленные исходники.
Так как изучать работу сокетов начал именно на этих исходниках, хочу спросить совета как решить возникшую проблему.
Я добавил автоконнект клиентов через 3 секунды после потери связи с сервером. Проверяю всё на одном компе локально. Клиентов запускаю батником 7-10 штук. Имя генерируется рандомоно, длиной 6 символов.
Проблема состоит в том, что при отключении сервера и повторном включении, один раз на 5-7 включений, при опросе имён клиентов происходит сбой. Я в мемо записываю все передачи и приём, и вот что происходит не правильно:
1) Сервер регистрирует многочисленные подключения.
2) Он рассылает 1 для опроса имени в каждый канал.
3) Клиент получает 1 и отправляет свой ник. Размер строки 7 символов. (Я убрал шрифты и цвета).
4) Сервер проверяет каналы и получает ответы. В идеале должно придти 7 отправленных символов. Проверяю так же с помощью ServerSocket.Socket.Connections[i-1].ReceiveLength, но на некоторых каналах длинна полученной строки удвоена. Причём ReceiveLength тоже указывает на удвоеный размер приёма.

С чем может быть связана эта проблема ? При 30 подключениях ошибка выскакивает постоянно, пакеты приходят не только удвоенные, но и утроенные.
ToBad вне форума Ответить с цитированием
Старый 22.11.2008, 15:03   #63
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

ToBad, у TCP/IP есть одна особенность, если вы подряд отправите три пакета, это не означает, что они придут как три пакета и обработаются каждый в отдельности, ...для снижения нагрузки на сеть эти три пакета могут объединиться в один, без нашего вмешательства, и соответственно, размер пакета будет в три раза больше, и обработаются только первые несколько байт по шаблону, остальные будут либо проигнорированы, либо сочтутся за команду и выскочит ошибка, если программист этого не предусмотрел. В своем примере я вообще ничего не предусматривал, поскольку это дело уже каждого лично, гораздо большую пользу имеет сам способ организации связи. Решение тут простое, введите в шаблон команды после байта индекса - байт длины пакета, напишите процедуру, которая принимает на обработку пакеты любой длины и вырезает из них отдельные команды. Принцип примерно такой:
1) передаем пакет;
2) смотрим первый байт, определяем команду;
3) смотрим следующий байт, определяем длину части;
4) вырезаем команду из пакета, обрабатываем;
5) если весь пакет больше длины вырезанной части, переходим к этой части и выполняем с пункта 2.

Обратите внимание, что при подключении нового пользователя идет опрос всех уже присутствующих. Здесь нужно строго следить, чтобы прием и отправка по одному взятому каналу выполнялась в нужной последовательности.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 22.11.2008, 15:16   #64
ToBad
 
Регистрация: 20.12.2007
Сообщений: 3
По умолчанию

Beermonza, спасибо за быстрый ответ !
Насчёт длины пакета - так и сделаю, но странно то, что неправильные данные просто дублируются 2-3 раза. То есть сервер посылает 3 запроса на Comp1-Copm3, а в ответ получает тоже 3 пакета, но такого вида:
1Comp1
1Comp21Comp2
1Comp3

Попробую передавать длину, это должно помочь. Ещё хотел бы спросить, какие неприятности могут ожидать при большом числе клиентов, например 150-200. У длины передаваемой строки есть ограничение в 255 символов ? Можно ли избежать опроса всех пользователей при коннекте или дисконнекте нового ? Есть ли возможность формировать и изменять юзер лист при срабатывании ServerSocketClientConnect и ServerSocketClientDisconnect ? Как это лучше реализовать ? Я в сокетах очень большой новичёк...
ToBad вне форума Ответить с цитированием
Старый 22.11.2008, 15:55   #65
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Цитата:
Сообщение от ToBad
Насчёт длины пакета - так и сделаю, но странно то, что неправильные данные просто дублируются 2-3 раза. То есть сервер посылает 3 запроса на Comp1-Copm3, а в ответ получает тоже 3 пакета, но такого вида:
1Comp1
1Comp21Comp2
1Comp3
Ищите ошибки в клиентской части, ваша система рандомайза возможно дает сбой, и шлет вместо одного пакета несколько, или каким-либо образом дублирует пакет перед отправкой. Сервер не может дублировать данные, он их только пересылает по числу каналов, строго одну копию в каждый, не более того.

Цитата:
Сообщение от ToBad
Ещё хотел бы спросить, какие неприятности могут ожидать при большом числе клиентов, например 150-200.
Данная система достаточно устойчиво должна работать, независимо от числа пользователей. Таймер задает интервал опроса, если пользователей будет много и они будут то подключаться, то снова отключаться, можно будет заметить медлительность обновления информации. Используйте управление интервалом, по принципу "чем больше пользователей, тем меньше интервал".

Цитата:
Сообщение от ToBad
У длины передаваемой строки есть ограничение в 255 символов ?
Нет, ограничений нет, но как программист вы обязаны ограничить длину сообщений на определенном значении.

Цитата:
Сообщение от ToBad
Можно ли избежать опроса всех пользователей при коннекте или дисконнекте нового ?
Нет, данная система не использует стандартные события на подключение и отключение клиентов как прямой метод распознавания количества и состава пользователей, ...на них настроены только вызовы основного алгоритма опроса пользователей. Иначе не возможно определить какой клиент отпал или подключился без специальных данных в его личных пакетах, а это угроза для взлома. Поэтому система просто получает факт, что что-то изменилось и начинает всех опрашивать.

Цитата:
Сообщение от ToBad
Есть ли возможность формировать и изменять юзер лист при срабатывании ServerSocketClientConnect и ServerSocketClientDisconnect ? Как это лучше реализовать ? Я в сокетах очень большой новичёк...
Эта система обновления уже встроена, на событиях ServerSocketClientConnect и ServerSocketClientDisconnect назначен флаг UpdDo обновления, который разрешает обновлять список пользователей в конце процедуры опроса.

Код:
// разрешение на выполнение процедур обновления
  If UpdDo=True then
    Begin
// обновляем массив пользователей
      UpdateUserMas;
// обновляем список пользователей
      UpdateUserList;
// блокируем разрешений
      UpdDo:=False;
    end;
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его

Последний раз редактировалось Beermonza; 22.11.2008 в 15:58.
Beermonza вне форума Ответить с цитированием
Старый 23.11.2008, 00:06   #66
ToBad
 
Регистрация: 20.12.2007
Сообщений: 3
По умолчанию

Beermonza большое спасибо за подсказки !
ToBad вне форума Ответить с цитированием
Старый 16.03.2009, 16:23   #67
bankir82
Новичок
Джуниор
 
Регистрация: 16.03.2009
Сообщений: 1
По умолчанию

подскажите пожалуйста, а как сделать чтобы если клиент запустился раньше сервера (или разрыв связи), то происходило переподключение к серверу? а то клиент тупо висит пока не нажмешь отключиться и снова подключиться.
Заранее благодарен
bankir82 вне форума Ответить с цитированием
Старый 18.03.2009, 13:06   #68
parinoff
 
Регистрация: 21.11.2008
Сообщений: 7
Вопрос Раздельные клиент-сервер

Привет всем! Отличная прога! Спасибо!

Но у меня возник вопросик как разнести сервер и клиент по разным приложениям?!
Напишите пожалуйста принцип.

Заранее спасибо!
parinoff вне форума Ответить с цитированием
Старый 19.03.2009, 16:15   #69
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию Режим ожидания сервера

Цитата:
Сообщение от bankir82 Посмотреть сообщение
подскажите пожалуйста, а как сделать чтобы если клиент запустился раньше сервера (или разрыв связи), то происходило переподключение к серверу? а то клиент тупо висит пока не нажмешь отключиться и снова подключиться.
Заранее благодарен
Создайте еще один таймер, в его теле запишите подключение:

Код:
procedure TForm1.ConnectTimerTimer(Sender: TObject);
begin
  ClientSocket.Active := True;
end;
Теперь нужен перехват ошибок сокета. Напишем собственную процедуру:
Код:
procedure TForm1.ClException(Sender: TObject; Error: Exception);
begin
  If (Error.ClassName = 'ESocketError') then
    Begin
      // снова пытаемся подключиться через таймер 1 раз в секунду
      ConnectTimer.Enabled := True;
      // меняем надпись клавиши
      ClientBtn.Caption:='Ожидание...';
    end
  else Application.ShowException(Error);   // ошибки не сокета пусть показывает
end;
Добавим в FormCreate связку с процедурой обработки ошибок:

Код:
procedure TForm1.FormCreate(Sender: TObject);
begin
// пусть обработка ошибок идет через специальную процедуру
  Application.OnException := ClException;

  ...
Процедура обработки соединения клиентского сокета теперь выглядит вот так:

Код:
procedure TForm1.ClientSocketConnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
// добавим в ChatRichEdit сообщение о соединении с сервером
// сразу зададим параметры шрифта (Arial, 8, красный, курсив)
  ShowColorMassage('00119['+TimeToStr(Time)+']  Подключение к серверу.', 2);
// подключаться больше не нужно
  ConnectTimer.Enabled := False;
// меняем надпись клавиши
  ClientBtn.Caption:='Отключиться';
end;
Вместо запуска сокета в процедуре клавиши ClientBtn будет запуск таймера:
Код:
procedure TForm1.ClientBtnClick(Sender: TObject);
begin
  If ClientBtn.Tag=0 then
    Begin
      ...
      // запускаем клиента
      ConnectTimer.Enabled := True;
      ...
Интервал у ConnectTimer ставим 1000 мс (можно больше), по-умолчанию он выключен (Enabled = False).
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 19.03.2009, 16:20   #70
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию Принцип клиент-сервера

Цитата:
Сообщение от parinoff Посмотреть сообщение
... как разнести сервер и клиент по разным приложениям?! Напишите пожалуйста принцип.
Достаточно просто. Программа и сейчас является клиент-серверной. Вам не нужны будут коды управления клиентским сокетом и некоторые его клавиши. Нужно сделать копию с архива, зайти в среду Delphi и вырезать все, что связано с ClientSocket для серверной части, и в другом проекте вырезать все, что связано с ServerSocket для клиентской части.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 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