Модераторы: gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ошибка при вызове Close 
:(
    Опции темы
FREEDEV
Дата 27.6.2007, 23:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 238
Регистрация: 6.3.2007
Где: Украина->Одесс а

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



Создаю асинхронный сервер, вот часть кода:
Код

        private Socket _serverSocket;
        private int _port;
        // настраиваем Socket
        private void SetupServerSocket()
        {
            // разрешаем соединение на любой из адресов сервера
            IPEndPoint myEndpoint = new IPEndPoint(
               IPAddress.Any, _port);

            // Создаем сокет, привязываем его к адресу
            // и начинаем прослушивание
            
            _serverSocket = new Socket(
                myEndpoint.Address.AddressFamily,
                SocketType.Stream, ProtocolType.Tcp);

            _serverSocket.Bind(myEndpoint);

            _serverSocket.Listen((int)
            SocketOptionName.MaxConnections);     
            
        }
        public void Start()
        {
            SetupServerSocket();
                _serverSocket.BeginAccept(new
                    AsyncCallback(AcceptCallback), _serverSocket);

        }
        private void AcceptCallback(IAsyncResult result)
        {
            ConnectionInfo connection = new ConnectionInfo();
            try
            {
                // Завершение операции Accept
                Socket s = (Socket)result.AsyncState;

                    connection.Socket = s.EndAccept(result);    // отсюда вываливаюсь !
                    connection.Buffer = new byte[255];
                    lock (_connections) _connections.Add(connection);

                    // Начало операции Receive и новой операции Accept
                    connection.Socket.BeginReceive(connection.Buffer,
                        0, connection.Buffer.Length, SocketFlags.None,
                        new AsyncCallback(ReceiveCallback),
                        connection);

                    // ждем запроса соединения
                    _serverSocket.BeginAccept(new AsyncCallback(
                        AcceptCallback), result.AsyncState);

            }
            catch...
        }



Проблема заключается в том, что при попытке закрыть сокет методом _serverSocket.Close
происходит вызов AcceptCallback с параметром отличным от Socket, что естественно выкидывает в обработчик исключения. Кто-то встречался с такой штукой, почемуу происходит попытка соединения по закрытию сокета, кем она инициирована
--------------------
Microsoft Windows Visla ©
PM MAIL   Вверх
stab
Дата 28.6.2007, 00:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1839
Регистрация: 1.1.2003

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



ну дык, а какое исключение? тут не телепаты собираются )

_serverSocket.Close когда вызывается? точнее, после вызова Start() что происходит дальше?


--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
tol05
Дата 28.6.2007, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



1. Что такое ConnectionInfo ?
2. у меня написало "Cannot access a disposed object." Что вполне логично, т.к. Close() у сокета вызывает Dispose()
Я бы вообще не использовал AcceptCallback() и EndAccept(), а писал бы
Код

_serverSocket.BeginAccept(null, null);

Или использовал, но добавил бы булев флаг (аналог bool disposed) в AcceptCallback() и после вызова close() его устанавливал, а в AcceptCallback()  - проверял его наличие
Код

bool closed;

static void Main(string[] args)
{
    Start();
    ...
    _serverSocket.Close();
    closed = true;
...
}        }

private static void AcceptCallback(IAsyncResult result)
{
    if(closed) return;
...
}



Цитата(FREEDEV @  27.6.2007,  23:54 Найти цитируемый пост)
почемуу происходит попытка соединения по закрытию сокета, кем она инициирована

тобой. Socket.EndAccept(...)
Цитата

Асинхронно принимает входящие попытки подключения и создает новый объект Socket для связи с удаленным узлом

http://msdn.microsoft.com/library/rus/defa...accepttopic.asp




--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
FREEDEV
Дата 28.6.2007, 12:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 238
Регистрация: 6.3.2007
Где: Украина->Одесс а

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



Цитата(tol05 @  28.6.2007,  09:42 Найти цитируемый пост)
"Cannot access a disposed object."

да именно это исключение и происходит.

Цитата(tol05 @  28.6.2007,  09:42 Найти цитируемый пост)
Цитата(FREEDEV @  27.6.2007,  23:54 )почемуу происходит попытка соединения по закрытию сокета, кем она инициированатобой. Socket.EndAccept(...)

имелось ввиду, почему я вообще попадаю в AcceptCallback, если никто не просится соединиться, единственный раз когда я туда захожу это после вызова Close(); далее уже EndAccept выпадает в ObjectDisposedException т.к. сокет закрыт

С флагом это ясное дело, но пока оставлю на закуску, т.к. это не совсем правильный вариант  - хочется разобраться в проблемме.
Пытался проверить на  _serverSocket.IsBound , но он всегда тру

Целью всех манипуляций является попытка отрубить сокет, а потом заново привязать его , но например уже к другому порту.
Пример честно  содран отсюда http://www.microsoft.com/Rus/Msdn/Magazine...08/Winsock.mspx

Это сообщение отредактировал(а) FREEDEV - 28.6.2007, 12:30
--------------------
Microsoft Windows Visla ©
PM MAIL   Вверх
tol05
Дата 28.6.2007, 12:49 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Потому что это сделано намеренно!
Если ты начинаешь выполнять любую операцию асинхронно, ты вызываешь метод BeginXXX, отдаешь ему делегат обратного вызова и надеешься на винду полностью. Она сообщит тебе колбеком об окончании и даст резуьтат. Правильно?
А если что-то случилось в винде? Если сбой, ошибка? Все пропало и никто ничего не понял... Как потом, после всего этого винде доверять? smile

Поэтому сделано так (причем для любых асинхронных операций, потоковых чтения\записи, Invoke, вообще для всего APM-ного):
Цитата

При обработке запроса на асинхронный ввод-вывод драйвером устройства Windows может произойти сбой, и Windows должна сообщить об этом  приложению. В частности, Windows ожидает поступление данных из сети лишь в течение указанного вызывающим кодом времени. Если данные не поступят вовремя, ОС должна сообщить пользователю об ошибке асинхронной операции. Для этого Windows передает уведомление в пул потоков CLR. Приложение «стыкуется» с результатами операции, вызывая метод EndXxx. Обычно EndXxx возвращает  
результат операции в приложение, но, если операция не была выполнена, EndXxx сгенерирует исключение. Тип исключения зависит от причины сбоя операции. 

Рихтер. "C# via .Net.djvu" Модель АРМ и исключения. 

когда ты вызываешь Close() (или Dispose()) для твоего сокета, асинхронный поток прерывается. Потоки прерываются, создавая (как известно) исключение  ThreadAbortException. Ну, а дальше - читай текст выше smile твой колбек вызывается в процессе обработки исключения

Это сообщение отредактировал(а) tol05 - 28.6.2007, 12:50


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
FREEDEV
Дата 28.6.2007, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 238
Регистрация: 6.3.2007
Где: Украина->Одесс а

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



Спасибо, теперь ясно, до Рихтера просто еще не добрался
--------------------
Microsoft Windows Visla ©
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
cully
mr.DUDA
Exception

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, cully, mr.DUDA, Exception.

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


 




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


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

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