Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Сети > TServerSocket ошибка 10053


Автор: dimokx87 22.4.2010, 12:55
Помогите пожалуйста!
Использую компонент TServerSocket, подключаются несколько клиентов, всё отлично работает. Но если выключить один из клиентов не разъединив соединение (например через диспетчер задач), то на сервере вылетает ошибка 10053, при этом сервер думает, что тот клиент ещё подключен. Что нужно сделать? smile 

Автор: Демо 22.4.2010, 13:51
Цитата(dimokx87 @  22.4.2010,  12:55 Найти цитируемый пост)
Что нужно сделать?


Ну видимо просто обработать эту ошибку (WSAECONNABORTED (10053))?

Автор: dimokx87 22.4.2010, 14:05
Подскажи пожалуйста как это сделать.

Автор: kami 22.4.2010, 17:46
Минимальный обработчик события OnError на серверном и клиентском сокете должен состоять из:
Код

ErrorCode:=0;
Socket.Close;

Автор: dimokx87 22.4.2010, 19:05
ErrorCode:=0; это у меня и так стоит, а Socket.Close; мне не нужно. Мне нужно, чтобы список пользователей обновился.

Автор: kami 22.4.2010, 20:36
Цитата(dimokx87 @  22.4.2010,  19:05 Найти цитируемый пост)
а Socket.Close; мне не нужно. 

Тогда без комментариев.
Только не удивляйтесь, что пошли утечки.

При "неправильном" разрыве соединения (прерывание процесса, разрыв соединения с помощью TCPView) "второму концу" это не сообщается. И узнает он о том, что соединение уже не живое только при попытке что-либо отправить в сокет. Именно в этот момент возникнет ошибка, которая должна быть обработана в OnError. Если ошибка все равно "вылезает", значит она не обработана, ибо исключение при ErrorCode=0 не возникает.
Код

    Error(Self, ErrorEvent, ErrorCode);
    if ErrorCode <> 0 then
      raise ESocketError.CreateResFmt(@sASyncSocketError, [ErrorCode]);


В догонку - при ошибке соединения его нужно закрыть установленным порядком.

Автор: dimokx87 22.4.2010, 21:00
Не могу понять. Значит закрытие сокета обязательно и придётся очистить список подсоединенных клиентов, а потом подключать всех заново?

Автор: kami 22.4.2010, 21:06
Цитата(dimokx87 @  22.4.2010,  21:00 Найти цитируемый пост)
Значит закрытие сокета обязательно и придётся очистить список подсоединенных клиентов, а потом подключать всех заново?

Видимо, Вы не правильно понимаете основы работы компонентов TClient|TServerSocket.
Команда Socket.Close, вызванная в одном из обработчиков событий этих компонентов приведет только к закрытию соединения, инициировавшего это событие. Говоря более простым языком - закроется только одно из соединений с клиентами. Только то, которое инициировало событие. На остальные соединения это никак не повлияет.
Не нужно путать ServerSocket.Socket, который является слушающим сокетом с ServerSocket.Socket.Connections[i], которые являются активными сокетами, обслуживающими только свои соединения. В события компонентов передается именно один из ServerSocket.Socket.Connections[i]

Автор: dimokx87 22.4.2010, 21:30
Всё работает!!! smile 
ОГРОМНОЕ спасибо kami!
Как я понял Socket.Close вызывает выполнение disconect.

Автор: kami 22.4.2010, 21:41
Цитата(dimokx87 @  22.4.2010,  21:30 Найти цитируемый пост)
Всё работает!!!

 smile 
отлично.
(мысли в слух: оно могло начать работать еще в http://forum.vingrad.ru/index.php?showtopic=298318&view=findpost&p=2140717 smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)