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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 02.01.2013, 11:52   #701
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,897
По умолчанию

Суть от этого не меняется. Приложение в любом случае падает. Походу такую ошибку не перехватить. Заметил, что падать сервер начинает при двух и более подключениях, при одном подключении такого нет.
И почему нет никакой реакции на клиентах при отключении инет кабеля на сервере? Ни дисконнект, ни ошибка сокета не срабатывают.
Код:
// Клиент
procedure TFormMain.ClientSocket1Disconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  if not ManualDisconnect then // Не ручное отключение
  begin
    // Оповещение в StatusBar
    ShowOnStatusBar('', 'Offline', '');
    // Очищаем список клиентов
    LVUsers.Clear;
    // Очищаем чат
    ClearChat;
    // Блокируем кнопки
    AccessControl(False, False);
    // Подключаемся
    TimerConnect.Enabled := True;
  end;
end;

procedure TFormMain.ClientSocket1Error(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
  ReConnect;
end;

procedure TFormMain.ReConnect;
begin
  // Оповещение в StatusBar
  ShowOnStatusBar('Ожидание подключения к серверу...', 'Offline', '');
  // Очищаем список клиентов
  LVUsers.Clear;
  // Очищаем чат
  ClearChat;
  // Отключаемся
  ClientSocket1.Close;
  // Блокируем кнопки
  AccessControl(False, False);
  // Подключаемся
  TimerConnect.Enabled := True;
end;

procedure TFormMain.ConnectToChat(FastConnect: Boolean);
begin
  // Запишем указанный порт в ClientSocket1
  ClientSocket1.Port := ChatPort;
  // Запишем хост и адрес (одно значение ChatHost в оба)
  ClientSocket1.Host := ChatHost;
  ClientSocket1.Address := ChatHost;
  // Запускаем клиента
  if FastConnect then ClientSocket1.Open else TimerConnect.Enabled := True;
end;

Последний раз редактировалось Shouldercannon; 02.01.2013 в 13:47.
Shouldercannon вне форума Ответить с цитированием
Старый 02.01.2013, 17:16   #702
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Цитата:
Сообщение от Shouldercannon Посмотреть сообщение
Суть от этого не меняется. Приложение в любом случае падает.
Если приложение показывает ошибку при запуске EXE непосредственно, то обработка не прописана, ...другого не дано.

Пропиши вот так и узнаешь:

Код:
procedure TFormMain.SocketException(Sender: TObject; Error: Exception);
begin
  FormMain.Caption := '';

  if (Error.ClassName = 'ESocketError') then FormMain.Caption := 'Ошибка сокета!'
  else FormMain.Caption := 'Ошибка приложения!';
end;
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 02.01.2013, 19:26   #703
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,897
По умолчанию

Так Ошибка сокета
Код:
procedure TFormMain.SocketException(Sender: TObject; Error: Exception);
begin
  FormMain.Caption := '';

  if (Error.ClassName = 'ESocketError') then FormMain.Caption := 'Ошибка сокета!'
  else FormMain.Caption := 'Ошибка приложения!';
end;
Так падение приложения
Код:
  if (Error.ClassName = 'ESocketError') then
  begin
    UpdateUserMas;
    UpdateUserList;
  end
  else SLError.Add(Format('%s - %s', [FormatDateTime('dd.mm.yyyy hh:mm:ss', Now), Error.Message]));
Получается, что сервер потерял связь с клиентами и это вызвало ошибки сокета, так мы ещё при этом опрашиваем клиентов и получаем фатальную ошибку.
Shouldercannon вне форума Ответить с цитированием
Старый 02.01.2013, 23:39   #704
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Shouldercannon, ставь проверку в секциях опроса каналов на состояние сокета, после потери связи условие не должно позволить "сканировать" каналы.

А у клиента за счет перехвата ошибок, работает проверка на подключение.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 03.01.2013, 20:40   #705
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,897
По умолчанию

Из-за этого места происходит падение
Код:
procedure TFormMain.UpdateUserMas;
begin
  if ServerSocket1.Socket.ActiveConnections > 0 then
  begin
    // Очищаем массив
    for i := 1 to 255 do
    begin
      UserMas[i].Status := 0;
    end;

    // Заполняем данные пользователей
    for i := 1 to ServerSocket1.Socket.ActiveConnections do
    begin
      UserMas[i].Status := 2;
      UserMas[i].Nick := 'Неизвестный';
      UserMas[i].Image := 1;
      // Запрашиваем имя (ник) пользователя по его каналу
      ServerSocket1.Socket.Connections[i - 1].SendText('10'); // Если закомментировать, то приложение не падает
    end;
  end;

  // Сброс авторизации
  Autores := 0;
end;
Цитата:
Сообщение от Beermonza Посмотреть сообщение
А у клиента за счет перехвата ошибок, работает проверка на подключение.
Видно при вылете сервера у клиента это событие не срабатывает

Последний раз редактировалось Shouldercannon; 03.01.2013 в 20:43.
Shouldercannon вне форума Ответить с цитированием
Старый 03.01.2013, 22:58   #706
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Цитата:
Сообщение от Shouldercannon Посмотреть сообщение
Видно при вылете сервера у клиента это событие не срабатывает
Значит ты где-то нарушил структуру. У меня BZChat 2_0 работает исправно, никаких ошибок. При завершении работы сервера через Диспетчер, клиенты переходят в режим "Ожидание..." и находятся в нем, пока не появится сервер по такому же IP. Если запустить клиенты и не запускать сервер, клиенты так же ждут. Если Сервер работает и завершить работу клиентов, сервер обновляет список и работает с еще подключенными. Корректное завершение работы обоих режимов отображается в поле чата.

Ни единой ошибки BZChat 2_0 не выдает, всё предельно корректно. Ищи баг вмешательства в код.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 04.01.2013, 19:39   #707
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,897
По умолчанию

Цитата:
Сообщение от Beermonza Посмотреть сообщение
Значит ты где-то нарушил структуру. У меня BZChat 2_0 работает исправно, никаких ошибок. При завершении работы сервера через Диспетчер, клиенты переходят в режим "Ожидание..." и находятся в нем, пока не появится сервер по такому же IP. Если запустить клиенты и не запускать сервер, клиенты так же ждут. Если Сервер работает и завершить работу клиентов, сервер обновляет список и работает с еще подключенными. Корректное завершение работы обоих режимов отображается в поле чата.

Ни единой ошибки BZChat 2_0 не выдает, всё предельно корректно. Ищи баг вмешательства в код.
При завершении работы сервера через Диспетчер, клиенты переходят в режим "Ожидание..." и находятся в нем, пока не появится сервер по такому же IP - есть
Если запустить клиенты и не запускать сервер, клиенты так же ждут - есть
Если Сервер работает и завершить работу клиентов, сервер обновляет список и работает с еще подключенными - есть
Решение проблемы:
Код:
procedure TFormMain.ProgramException(Sender: TObject; Error: Exception);
begin
  if (Error.ClassName = 'ESocketError') then
  begin
    UpdateUserMas;
    UpdateUserList;
  end
  else SLError.Add(Format('%s - %s', [FormatDateTime('dd.mm.yyyy hh:mm:ss', Now), Error.Message]));
end;
меняем на
Код:
procedure TFormMain.ProgramException(Sender: TObject; Error: Exception);
begin
  if (Error.ClassName = 'ESocketError') then
  begin
    // Разрешаем обновление
    UpdMas := True;
  end
  else SLError.Add(Format('%s - %s', [FormatDateTime('dd.mm.yyyy hh:mm:ss', Now), Error.Message]));
end;
Осталось разобраться в клиентами в момент отключения сервера от сети, ведь на клиентах в этот момент ни одно из событий сокета не срабатывает и ошибок нет, клиенты просто висят со статусов Online. Как вариант завести ещё один таймер для проверки связи с сервером.

Последний раз редактировалось Shouldercannon; 05.01.2013 в 00:39.
Shouldercannon вне форума Ответить с цитированием
Старый 05.01.2013, 17:09   #708
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

У меня клиенты не "висят", ...это зависит от интервала таймера.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 05.01.2013, 18:08   #709
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,897
По умолчанию

Цитата:
Сообщение от Beermonza Посмотреть сообщение
У меня клиенты не "висят", ...это зависит от интервала таймера.
Имел ввиду, что клиент не повисает, тоесть не зависает, не становится не доступным, он просто находится в режиме Online.
Shouldercannon вне форума Ответить с цитированием
Старый 07.01.2013, 16:55   #710
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,897
По умолчанию

Забыл почему на сервере цикл с 1 по количество подключений, а отправка ведётся в канал - 1
Код:
procedure TFormMain.PLVUMRefreshNickClick(Sender: TObject);
begin
  if LVUsers.Items.Count > 1 then
  begin
    for i := 1 to ServerSocket1.Socket.ActiveConnections do
    begin
      if UserMas[i].Nick = LVUsers.Items[LVUsers.ItemIndex].Caption then
      begin
        ServerSocket1.Socket.Connections[i - 1].SendText('11');
      end;
    end;
  end;
end;
Это из-за клиента, который поумолчанию создаётся?
Shouldercannon вне форума Ответить с цитированием
Ответ


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