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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Асинхронные сокеты 
:(
    Опции темы
Lazin
Дата 24.3.2008, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



Пытаюсь использовать неблокирующие сокеты таким-вот нехитрым способом:

подключение:

Код

        public void Connect( IPEndPoint ipep)
        {
            socket_.BeginConnect(ipep, new AsyncCallback(OnConnect), socket_);
        }

        private void OnConnect(IAsyncResult ar)
        {
            Socket socket = (Socket)ar.AsyncState;
            socket.EndConnect(ar);
            ReadNext();
        }


чтение данных
Код


       private void ReceiveSize() //чтение заголовка пакета (размер и тип данных пакета)
        {
            byte[] sz_buffer = new byte[8];
            socket_.BeginReceive(sz_buffer, 0, 8, 0, new AsyncCallback(OnReceiveSize), sz_buffer);
        }

        private void OnReceiveSize(IAsyncResult ar)
        {
            byte[] sz_buffer = (byte[])ar.AsyncState;
            int bytes_read = socket_.EndReceive(ar);
            if (bytes_read < 8)
            {
                socket_.BeginReceive(sz_buffer, 0, 8, 0, new AsyncCallback(OnReceiveSize), sz_buffer);
            }
            else
            {   //получили размер и тип пакета, создаем пакет и пытаемся его читать
                uint size = BitConverter.ToUInt32(sz_buffer, 0);
                int type = BitConverter.ToInt32(sz_buffer, 4);
                Packet packet = new Packet(size - 8, type);//создание пакета (мой класс - просто массив с несколькими дополнительными параметрами)
                socket_.BeginReceive(packet.get_data(), 0, (int)size - 8, 0, new AsyncCallback(OnReceivePacket), packet); 
            }
        }

        private void OnReceivePacket(IAsyncResult ar)
        {
            Packet packet = (Packet)ar.AsyncState;
            int bytes_read = socket_.EndReceive(ar);
            if (bytes_read < packet.size - 8)
            {
                socket_.BeginReceive(packet.get_data(), 0, (int)packet.size - 8, 0, new AsyncCallback(OnReceivePacket), packet);
            }
            else
            {
                in_queue_.Enqueue(packet);//пакет прочитан полностью, добавляем его в очередь
                on_receive_.Set();//событие AutoResetEvent
                ReadNext();//начинаем читать следующий пакет...
            }
        }

        public void ReadNext()//чтение следующего пакета
        {
            ReceiveSize();
        }


а проблема здесь.. 
Код

        public void Disconnect()
        {
            socket_.BeginDisconnect(false, new AsyncCallback( OnDisconnect ), null);
        }

        public void OnDisconnect(IAsyncResult ar)
        {
            socket_.EndDisconnect(ar);
            socket_.Shutdown(SocketShutdown.Both);
            socket_.Close();
            ar.AsyncWaitHandle.WaitOne();
        }

все это работает пока я не закрываю сокет
после того как я вызываю метод Disconnect, спустя какое-то время вызывается колбэк OnReceiveSize, и при вызове EndReceive происходит ошибка - "Cannot access a disposed object."
видимо я как-то непраильно работаю с сокетом...

как правильно синхронизировать это все?

Добавлено через 1 минуту и 45 секунд
ps
это все методы класса, socket_ - Socket smile
PM MAIL Skype GTalk   Вверх
WERITAS
Дата 27.3.2008, 09:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


********
**


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

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



Доброго времени суток.
Когда-то столкнулся с такой же проблемой: постоянно при отключении сокета-сервера вылетало исключение. В конце концов я стал делать просто:
Код

socket_.Close();

Если я не ошибаюсь, в MSDN написанно, что эта операция закрывает сокет и освобождает занятые им ресурсы. Осмелюсь предположить, что под "освобождением ресурсов" понимается и завершение порожденных объектом потоков (прямо как в Линуксе), поэтому программа не "кричит" на асинхронную операцию чтения.


--------------------
Арт-менеджер клуба, разрешивший концерт Алексея Глызина, уволен с формулировкой "Мудак"
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
cully
mr.DUDA
Exception

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

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

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


 




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


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

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