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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Не получается второй раз приконнектиться к серверу, Проблема с закрытием сокета 
V
    Опции темы
Competitor
Дата 2.7.2007, 10:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Привет всем!
Есть клиент и сервер. Взаимодействуют они через сокеты. После запуска проги-сервера, клиент без проблем к нему коннектиться и работает как надо. Если клиент закрыть, то при втором запуске он уже не может нормально взаимодействовать с сервером. Не выдает никаких Exceptions, но и данные тоже не передаются. Нормальная работа возобновляется только после перезапуска сервака.
Так закрывает коннектион сервер:
Код

        public bool Disconnect()
        {
            TraceProvider.Write("Disconnect() method is called");
            if (this.socket != null && this.socket.Connected)
            {
                try
                {
                    this.socket.Shutdown(SocketShutdown.Both);
                    this.socket.Close();
                    return true;
                }
                catch
                {
                    return false;
                }
            }
            else
                return true;
        } 

После закрытия консоли (клиента) этот метод всегда срабатывает.
На клиенте при закрытии также срабатывает дисконнект.

Во, только щас заметил, что соединение разрывается с исключением на клиенте:
Unable to read data from the transport connection: A blocking operation was interrupted by a call to WSACancelBlockingCall
Что это может значить и как попробовать решить проблему?
Спасибо
PM MAIL WWW   Вверх
stab
Дата 2.7.2007, 10:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



код сервера в студию.


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


Опытный
**


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

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



После второго запуска клиента взаимодействие нарушается, но если подождать подольше, то на клиенте вылетает такой exception:
Код

SendCommandToServer method failed with exception: Unable to write data to the transport connection: Cannot access a disposed object.
Object name: 'System.Net.Sockets.Socket'..


PM MAIL WWW   Вверх
stab
Дата 2.7.2007, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



код клиента тоже в студию )


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


Опытный
**


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

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



Начинается все вот так:
Код

public ClientManager(Socket socket)
        {
            this.socket = socket;
            this.networkStream = new NetworkStream(this.socket);
            this.bwReceiver = new BackgroundWorker();
            this.bwReceiver.DoWork += new DoWorkEventHandler(StartReceive);
            this.bwReceiver.RunWorkerAsync();
        }


Вот здесь сервак крутится асинхронно получая сообщения:
Код

        private void StartReceive(object sender, DoWorkEventArgs e)
        {
            try
            {
                while (this.socket.Connected)
                {
                    //Read the command's Type.
                    byte[] buffer = new byte[4096];
                    int readBytes = this.networkStream.Read(buffer, 0, buffer.Length);
                    if (readBytes == 0)
                        break;
                    Command cmd = new Command(buffer);
                    this.OnCommandReceived(new CommandEventArgs(cmd));
                }
            }
            catch(Exception ex) 
            {
                TraceProvider.Write("StartReceive method failed with exceptiom: {0} in the assembly: {1}", ex.Message, Assembly.GetExecutingAssembly().FullName);
            }
            finally
            {
                this.OnDisconnected(new ClientEventArgs(this.socket));
                this.Disconnect();
            }
        }


Добавлено через 2 минуты и 2 секунды
Отправка сообщений сервером по той же схеме:
Код

        public void SendCommand(Command cmd)
        {
            if (this.socket != null && this.socket.Connected)
            {
                BackgroundWorker bwSender = new BackgroundWorker();
                bwSender.DoWork += new DoWorkEventHandler(bwSender_DoWork);
                bwSender.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwSender_RunWorkerCompleted);
                bwSender.RunWorkerAsync(cmd);
            }
            else
                this.OnCommandFailed(new EventArgs());
        }


Асинхронно отправляем данные:
Код

private void bwSender_DoWork(object sender, DoWorkEventArgs e)
        {
            Command cmd = (Command)e.Argument;
            e.Result = this.SendCommandToClient(cmd);
        }
        System.Threading.Semaphore semaphor = new System.Threading.Semaphore(1, 1);
        private bool SendCommandToClient(Command cmd)
        {
            try
            {
                semaphor.WaitOne();
                this.networkStream.Write(cmd.Data, 0, cmd.Data.Length);
                this.networkStream.Flush();
                semaphor.Release();
                return true;
            }
            catch
            {
                semaphor.Release();
                return false;
            }
        }


Добавлено через 11 минут и 38 секунд
На клиенте так происходит коннект:
Код

this.clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                this.clientSocket.Connect(serverEP);
                //e.Result = true;
                connectionResult = true;
                this.networkStream = new NetworkStream(this.clientSocket);
                this.bwReceiver = new BackgroundWorker();
                this.bwReceiver.WorkerSupportsCancellation = true;
                this.bwReceiver.DoWork += new DoWorkEventHandler(StartReceive);
                this.bwReceiver.RunWorkerAsync();


Отправляет сообщение:
Код

BackgroundWorker bwSender = new BackgroundWorker();
                bwSender.DoWork += new DoWorkEventHandler(bwSender_DoWork);
                bwSender.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwSender_RunWorkerCompleted);
                bwSender.WorkerSupportsCancellation = true;
                bwSender.RunWorkerAsync(cmd);

        private void bwSender_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (!e.Cancelled && e.Error == null && ((bool)e.Result))
                this.OnCommandSent(new EventArgs());
            else
                this.OnCommandFailed(new EventArgs());

            ((BackgroundWorker)sender).Dispose();
            GC.Collect();
        }

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


Эксперт
***


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

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



ИМХО, когда ты выключаешь клиента, сервер выходит из цикла 
Код

while (this.socket.Connected)

и делает себе this.Disconnect(). Дальше из StartReceive выходим, и прекращается поток
Код

this.bwReceiver.DoWork += new DoWorkEventHandler(StartReceive);
this.bwReceiver.RunWorkerAsync();

А как сокет сервера опять на прослушку подключений станет?

Новый клиент пытается подключиться к сокету, а он - в disconnecte....


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


Опытный
**


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

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



Цитата

А как сокет сервера опять на прослушку подключений станет?

Вот так реализовано:
Код

            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socket.Bind(new IPEndPoint(serverIP, serverPort));
            socket.Listen(200);
            while (true)
            {
                CreateNewClientManager(socket.Accept());
            }

Т.е. новые клиенты могут подключаться когда угодно. Да и главное клиент то подключается, только данные не передаются.
Да, и небольшое уточнение, клиент тоже никогда не выключается (клиент реализован в виде сервиса). Если сервис перезапустить (охх), то все работает как часы. У меня же есть просто консоль, которая работает с вервером через сервис. Ее то и не получается запустить второй раз без перезапуска сервиса или сервера. Подключение к серваку хранит в себе сервис и я подозреваю, что после того как консоль закрывается, сервис не разрывает должным образом соединение. Достаточно ли этого чтобы полностью освободиться ресурсы:
Код

                    this.clientSocket.Shutdown(SocketShutdown.Both);
                    this.clientSocket.Close();
                    this.bwReceiver.CancelAsync(); //убиваем поток

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

Без разницы так тоже не работает. Короче поток виснет вот здесь:
Код

TraceProvider.Write("Trying to create new BackgroundWorker");
                BackgroundWorker bwSender = new BackgroundWorker();
                TraceProvider.Write("BackgroundWorker is created");
                bwSender.DoWork += new DoWorkEventHandler(bwSender_DoWork);
                bwSender.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwSender_RunWorkerCompleted);
                bwSender.WorkerSupportsCancellation = true;
                TraceProvider.Write("Parameters is setuped");
                bwSender.RunWorkerAsync(cmd);

RunWorkerAsync не запускает новый поток!!!! Причем делает это хаотично. Первый раз отрабатывает стабильно, а дальше как повезет.
Кто0-нить сталкивался с подобным.
PM MAIL WWW   Вверх
stab
Дата 2.7.2007, 14:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



tol05, что и требовалось доказать )

Competitor, ClientManager() откуда вызвается? и сколько раз?

Добавлено через 1 минуту и 13 секунд
.. вопрос снят )


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


Опытный
**


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

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



bwSender.RunWorkerAsync(cmd); запускает поток, но не сразу, а минут через 10. Как это возможно?
PM MAIL WWW   Вверх
Competitor
Дата 2.7.2007, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Перешел на старый добрый Thread, проблем больше не возникает (*постучал по голове)
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
cully
mr.DUDA
Exception

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

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

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


 




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


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

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