Модераторы: Snowy, Poseidon, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> TServerSocket/TClientSocket, не проходят сообщения, один из клиентов выпадает, разрушая цепо 
:(
    Опции темы
DelphiTester
Дата 14.5.2007, 20:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 3.5.2007

Репутация: нет
Всего: нет



У меня сервер рассылает по всем клиентам следующим кодом:
Код

for I := 0 to ServerSocket1.Socket.ActiveConnections-1 do
  ServerSocket1.Socket.Connections[I].SendText(Str);

Проблема в том, что если подключились подряд 5 клиентов и первый "выпал" (отконнектился), то сообщения проходить не будут и до остальных. Это можно как-нибудь обойти, чтобы вылетев один клиент не вмешивался в работу остальных?

PM MAIL   Вверх
drkot
Дата 14.5.2007, 20:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ищущий
***


Профиль
Группа: Завсегдатай
Сообщений: 1042
Регистрация: 5.5.2006

Репутация: 0
Всего: 8



клиент отключается как? disconnect или обрыв соединения?
попробуй обработку исключений.


--------------------
Ошибка не становится истиной по причине широкого распространения,
как и Истина не становится Ошибкой из-за того, что никто её не видит.
PM   Вверх
DelphiTester
Дата 15.5.2007, 01:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 3.5.2007

Репутация: нет
Всего: нет



Клиент отключается именно обрывом соединения.
А что в этой обработке исключений мне писать? Чего там надо обрабатывать? Не представляю как серверу указать, что клиент случайно вылетел..
PM MAIL   Вверх
drkot
Дата 15.5.2007, 10:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ищущий
***


Профиль
Группа: Завсегдатай
Сообщений: 1042
Регистрация: 5.5.2006

Репутация: 0
Всего: 8



После того как система закроет соединение по таймаут, передача данных продолжится.

Думаю в данном случае нужно создавать поток для каждого клиента, и 
думать над методом синхронизации (если это нужно).

Возможно стоит обратить внимание на протокол UDP.


--------------------
Ошибка не становится истиной по причине широкого распространения,
как и Истина не становится Ошибкой из-за того, что никто её не видит.
PM   Вверх
DelphiTester
Дата 15.5.2007, 10:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 3.5.2007

Репутация: нет
Всего: нет



На UDP не очень-то "хочется" обращать внимание. Клиентов относительно не много - 5-10. А использовать широковещательные запросы для такого кол-ва, не знаю, имеет ли смысл?

А самостоятельно нельзя ли закрывать соединение с клиентом которые отсоеденился?
PM MAIL   Вверх
Snowy
Дата 15.5.2007, 12:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



1. крути цикл в обратную сторону - от кол-ва до 0.
2. Перед отправкой, проверь, активен сокет или нет.
PM MAIL   Вверх
drkot
Дата 15.5.2007, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ищущий
***


Профиль
Группа: Завсегдатай
Сообщений: 1042
Регистрация: 5.5.2006

Репутация: 0
Всего: 8



Цитата(Snowy @  15.5.2007,  12:29 Найти цитируемый пост)
активен сокет или нет

насколько я знаю состояние активности не поможет.

Snowy, а в чем фокус?
Цитата(Snowy @  15.5.2007,  12:29 Найти цитируемый пост)
крути цикл в обратную сторону - от кол-ва до 0.


Цитата(DelphiTester @  15.5.2007,  10:22 Найти цитируемый пост)
 широковещательные запросы

а где я писал о широковещательных? 

просто TCP требует установления соединения, а UDP нет. В UDP обрыва соединения быть не может  smile 


--------------------
Ошибка не становится истиной по причине широкого распространения,
как и Истина не становится Ошибкой из-за того, что никто её не видит.
PM   Вверх
Snowy
Дата 15.5.2007, 13:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Цитата(drkot @  15.5.2007,  13:31 Найти цитируемый пост)
насколько я знаю состояние активности не поможет.
Ну мало ли... Может и поможет smile 

Помести SendText в try .. except. По except прибивай коннект.

Цитата(drkot @  15.5.2007,  13:31 Найти цитируемый пост)
Snowy, а в чем фокус?
Потому что пока ты крутишь цикл, кол-во соеденений может измениться в меньшую сторону. Тогда поймаешь глюку...

Так уж устроены сокеты.
Если клиент отвалился, не сообщив об этом, то сервер может не узнать об этом ещё некоторое время.
Причём это время может достигать получаса.
PM MAIL   Вверх
drkot
Дата 15.5.2007, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ищущий
***


Профиль
Группа: Завсегдатай
Сообщений: 1042
Регистрация: 5.5.2006

Репутация: 0
Всего: 8



Цитата(Snowy @  15.5.2007,  13:43 Найти цитируемый пост)
Тогда поймаешь глюку...

Тогда глюка бы имела вид обращения к несуществующему объекту.
А если клиент ушел по английски то при использовании TCP неизбежно напоришся на тиме оут  smile 

Выход один (в моем понимании) на каждого клиента свой поток, если поток начинает тупить то мы его прибиваем.

PS: и все таки UDP будет хорошей таблеткой от гимороя  smile 


--------------------
Ошибка не становится истиной по причине широкого распространения,
как и Истина не становится Ошибкой из-за того, что никто её не видит.
PM   Вверх
Snowy
Дата 15.5.2007, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Цитата(Snowy @  15.5.2007,  13:43 Найти цитируемый пост)
Помести SendText в try .. except. По except прибивай коннект.

PM MAIL   Вверх
Хрипа
Дата 15.5.2007, 17:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 11.12.2006

Репутация: нет
Всего: нет



Я делал иначи..
Опрашиваю клиентов в сети или нет.
И только  отсылаю тем что в сети..
проверку  Зделай

Это сообщение отредактировал(а) Хрипа - 15.5.2007, 17:43
--------------------
<Вырезана, как не соответствующая правилам форума >
PM MAIL   Вверх
DelphiTester
Дата 15.5.2007, 17:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 3.5.2007

Репутация: нет
Всего: нет



Snowy
2. А как проверить активен ли данный клиент? (соединение).
Я не нашёл подобных методов у клиента..

Хрипа
Данные передаются слишком часто, чтобы перед каждой передачей пытаться делать опрос.

drkot
Ты имел ввиду "ручную" рассылку циклом через UDP? Вообще UDP у меня ассоциируется с широковещательной рассылкой по сети.
PM MAIL   Вверх
Хрипа
Дата 15.5.2007, 21:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 11.12.2006

Репутация: нет
Всего: нет



DelphiTester
100% надо проверять Чел онлайн или нет..
Или использывать события онДисконект и базу данных любую хоть даже текстовую.
При дисконекте удалять с базы не верного юзера и при конекте добовлять (при помаши Timer1).
И только тем кто в базе отсылать данные. или хранить их всех и менять только режим Онлайн или нет... ну это тучь тяжелей без SQL

Это сообщение отредактировал(а) Хрипа - 15.5.2007, 21:38
--------------------
<Вырезана, как не соответствующая правилам форума >
PM MAIL   Вверх
DelphiTester
Дата 15.5.2007, 23:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 3.5.2007

Репутация: нет
Всего: нет



А как проверить онлайн он или нет??
Насколько я понял при таком "случайном вылете" клиента никаких ошибок не следует и обрабатывать нечего.. Как же узнать, что он отконнектился? Как опрос сделать? (надеюсь не послать ему строку и если он в ответ ответит..... Всё-таки такая технология совсем всю сеть загрузит и правда думать прийдётся о UDP протоколе.)
PM MAIL   Вверх
drkot
Дата 15.5.2007, 23:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ищущий
***


Профиль
Группа: Завсегдатай
Сообщений: 1042
Регистрация: 5.5.2006

Репутация: 0
Всего: 8



Цитата(Хрипа @  15.5.2007,  17:40 Найти цитируемый пост)
Опрашиваю клиентов в сети или нет.И только  отсылаю тем что в сети..

Класс!!!! Примерно так: подошел к двери, подергал - никого, позвонил - опять никого  smile 
Мммм да. Повесилил на ночь глядя.
Проверять как, бегать в соседний кабинет и смотреть работает ли прога ?
А если по TCP? то сиди и кури тайм оут.


DelphiTester, точно также как у тебя сделано, только немного сложнее.
тк контроль за соединением (если так можно выразится) обеспечивает программист, а не стек протокола (как в TCP). 

PS: а вобще читайте документацию или хотябы статейки.


--------------------
Ошибка не становится истиной по причине широкого распространения,
как и Истина не становится Ошибкой из-за того, что никто её не видит.
PM   Вверх
DelphiTester
Дата 16.5.2007, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 3.5.2007

Репутация: нет
Всего: нет



Цитата
DelphiTester, точно также как у тебя сделано, только немного сложнее.

Не понял.. а можно поподробнее о чём Вы хоть хотели сказать? smile Если "точно также как у тебя сделано", то у меня получается уже всё сделано, а чего оно не работает smile smile
Можно пример кода?
PM MAIL   Вверх
drkot
Дата 16.5.2007, 19:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ищущий
***


Профиль
Группа: Завсегдатай
Сообщений: 1042
Регистрация: 5.5.2006

Репутация: 0
Всего: 8



Под "точно также" понимается, что работа с udp практически такаяже как и с tcp

http://www.citforum.ru/internet/tifamily/udpspec.shtml


--------------------
Ошибка не становится истиной по причине широкого распространения,
как и Истина не становится Ошибкой из-за того, что никто её не видит.
PM   Вверх
DelphiTester
Дата 17.5.2007, 01:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 3.5.2007

Репутация: нет
Всего: нет



Но UDP использовать можно только в том случае, если не важно доходят данные или нет. А если важно? smile
Приходится опять о TCP думать и опять-таки вопрос. А как проверить не отвалился ли текущий клиент?
PM MAIL   Вверх
DelphiTester
Дата 17.5.2007, 17:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 3.5.2007

Репутация: нет
Всего: нет



Кто-нибудь что-либо сможет подсказать? например, как сделать проверку активности текущего клиента? (через TCP ессно)
PM MAIL   Вверх
Snowy
Дата 17.5.2007, 17:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



У клиента же и спросить...
PM MAIL   Вверх
DelphiTester
Дата 17.5.2007, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 3.5.2007

Репутация: нет
Всего: нет



Дык как спросить-то? smile Я же об этом с самого начало и говорю. Можно ли указать опцию/метод, позволяющий сделать это??
Вот здесь: "ServerSocket1.Socket.Connections[I].", я так и не смог найти как именно "спросить" клиента, активно ли именно с ним соединение в данный момент или нет..
PM MAIL   Вверх
DelphiTester
Дата 17.5.2007, 19:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 3.5.2007

Репутация: нет
Всего: нет



Пробовал посылку модифицировать так:
Код
    for I := ServerSocket1.Socket.ActiveConnections-1 downto 0 do begin

      try
        if ServerSocket1.Socket.Connections[I].Connected then
          ServerSocket1.Socket.Connections[I].SendText( PostStr );
      except
        Memo2.Lines.Add ( IntToStr ( I ) + ' falls' );
      end;

    end;

результатов не дало. except ни в каком случае не срабатывает. (т.е. не при выключенных клиентах, ни при отключенных, всегда условие "успешности" выполняется...

Как же в этом случае бороться с этой ерундой?
PM MAIL   Вверх
AugMaster
Дата 22.5.2007, 02:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 49
Регистрация: 3.8.2006

Репутация: 1
Всего: 1



выложи ПОЛНЫЙ код серверной проги, и будет тебе щастье. Потому как сейчаз хитрый случай походу, и мы тут на кофейной гуще гадаем.
PM MAIL   Вверх
drkot
Дата 22.5.2007, 09:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ищущий
***


Профиль
Группа: Завсегдатай
Сообщений: 1042
Регистрация: 5.5.2006

Репутация: 0
Всего: 8



DelphiTester,  smile 
Цитата(DelphiTester @  17.5.2007,  01:34 Найти цитируемый пост)
 А если важно?

Покупка билета еще не есть гарантия что попадеш на поезд (в театр и тд), но почемуто все покупают.

Одного желания (даже если оно очень большое) мало для достижения цели. Нужно эще иметь хотябы отдаленное представление о том что именно ты хочеш сделать, а главное КАК? Ответы на вопрос КАК обычно есть в толстых умных книжках. 
Из твоих слов могу сделать вывод, что о сетевых протоколах ты практически ничего не знаеш, принципа работы не понимаеш, а работать пытаешся. Парадокс, однако   smile 

Это сообщение отредактировал(а) drkot - 22.5.2007, 09:42


--------------------
Ошибка не становится истиной по причине широкого распространения,
как и Истина не становится Ошибкой из-за того, что никто её не видит.
PM   Вверх
DelphiTester
Дата 22.5.2007, 09:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 3.5.2007

Репутация: нет
Всего: нет



Согласен.


Проблема разрешилась, косяк был на моей стороне, это никак не относится к сокетам.

Добавлено через 2 минуты и 26 секунд
Предлагаю переключиться на другую мою проблему smile
http://forum.vingrad.ru/forum/topic-152421.html
PM MAIL   Вверх
Gwire
Дата 23.8.2007, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 216
Регистрация: 7.8.2007
Где: Николаев

Репутация: нет
Всего: 4



 smile
У TServerSocket есть такие события как:
    OnClientConnect;
    OnClientDisconnect;
    OnClientError.
TCustomWinSocket имеет свойства SocketHandle: Integer.
А также есть тип TList "хранящий" элементы типа Pointer. Замечу что SizeOf(Pointer) = SizeOf(Integer)

 smile
Как это тебе поможет?..
Код

  TForm1 = class(TForm)
    ServerSocket1: TServerSocket;
  private
  public
    ListClientTCP: TList; // Не забудь создать в TForm1.FormCreate!
  end;


Предположим, что клиент подключился...
Код

procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
    // Сохраняем Handle клиента под видом указателя
    ListClientTCP.Add( Pointer(Socket.SocketHandle) );
end;


Проходит время, клиент отключился...
Код

procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
    ListClientTCP.Remove( Pointer(Socket.SocketHandle) );
end;


А если клиента убило или разсоединило...
Код

procedure TForm1.ServerSocket1ClientError(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
    if ErrorCode = $2745 then
    begin
        ErrorCode:= 0;
        Socket.Close; // Сработает ServerSocket1ClientDisconnect
    end;
end;

Как читать из ListClientTCP учить тебя не буду (просто Integer(ListClientTCP.Items[i]) ).
Удачи.

PM MAIL   Вверх
AugMaster
Дата 26.8.2007, 01:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 49
Регистрация: 3.8.2006

Репутация: 1
Всего: 1



Цитата

Тогда глюка бы имела вид обращения к несуществующему объекту.
А если клиент ушел по английски то при использовании TCP неизбежно напоришся на тиме оут  

у меня прога на серверном сокете, кол-во соединений в среднем от 200 до 900. И глюка действительно имеет вид "OutBound"-чего-то там. Но смысл ее ловить, когда можно избежать этого,просто крутя цикл в обратную сторону ?

Насчет таймаут- когда роутер глюкавит, таймаут может достигать больших величин,и при этом при отправке клиенту данных никаких эрроров тебе не пишет, просто данные уходят в никуда. 

Это сообщение отредактировал(а) AugMaster - 26.8.2007, 01:13
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Сети"
Snowy
Poseidon
MetalFan

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Snowy, Poseidon, MetalFan.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.1164 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.