Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

udpclient разорвано соединение

268
24 января 2010 года
Михаил
587 / / 25.06.2005
Код:
Thread udpserver = new Thread
                (
                delegate()
                {
                    UdpClient udps = new UdpClient(7777);
                    IPEndPoint ipe=new IPEndPoint(IPAddress.Any,0);

                    while (true)
                    {
                        byte[] buffer = udps.Receive(ref ipe);
                        Console.WriteLine("{0} bytes were received from {1}", buffer.Length, ipe.ToString());
                        udps.Send(buffer, buffer.Length, ipe);
                    }
                }
                );
            udpserver.IsBackground = true;
           
            //tcpserver.Start();
            udpserver.Start();

           

            byte[] buf=new byte[10];
            int sent;

            Thread.Sleep(1000);
            using (UdpClient udpc = new UdpClient(1111))
            {
                udpc.Connect(new IPEndPoint(IPAddress.Loopback, 7777));
                IPEndPoint ipe=new IPEndPoint(IPAddress.Any,0);

                for (int i = 0; i < 3; i++)
                    udpc.Send(buf, buf.Length);
                while (udpc.Available > 0)
                {
                    buf = udpc.Receive(ref ipe);
                    Console.WriteLine("{0} bytes were received from {1}", buf.Length, ipe.ToString());
                }
                Thread.Sleep(10000);
            }

            Console.ReadKey();
            return;

если выполнять код пошагово, то все работает как надо, если нет, то выбрасывается исключение на выделенном участе, почему?
8.2K
24 января 2010 года
bagie2
299 / / 26.10.2008
может быть недостаточная синхронизация? например Sleep не очень удачно подходит для данной ситуации.
268
24 января 2010 года
Михаил
587 / / 25.06.2005
[LEFT]я не там поставил Sleep, вот тут работает нормально
Код:
Thread udpserver = new Thread
                (
                delegate()
                {
                    UdpClient udps = new UdpClient(7777);
                    IPEndPoint ipe=new IPEndPoint(IPAddress.Any,0);

                    while (true)
                    {
                        byte[] buffer = udps.Receive(ref ipe);
                        Console.WriteLine("{0} bytes were received from {1}", buffer.Length, ipe.ToString());
                        udps.Send(buffer, buffer.Length, ipe);
                    }
                }
                );
            udpserver.IsBackground = true;
           
            //tcpserver.Start();
            udpserver.Start();

           

            byte[] buf=new byte[10];
            int sent;

            using (UdpClient udpc = new UdpClient())
            {
                udpc.Connect(new IPEndPoint(IPAddress.Loopback, 7777));
                IPEndPoint ipe=new IPEndPoint(IPAddress.Any,0);

                for (int i = 0; i < 3; i++)
                    udpc.Send(buf, buf.Length);
                Thread.Sleep(100);
                while (udpc.Available > 0)
                {
                    buf = udpc.Receive(ref ipe);
                    Console.WriteLine("{0} bytes were received from {1}", buf.Length, ipe.ToString());
                }
            }

            Console.ReadKey();
            return;
но использовать Sleep это ненадежно, почему без него не работает?
как исправить
[/LEFT]
8.2K
24 января 2010 года
bagie2
299 / / 26.10.2008
А приложение само себе будет посылать данные?
268
24 января 2010 года
Михаил
587 / / 25.06.2005
сейчас посылает в одном потоке, в другом принимает, а разве есть разница в одном приложении или нет?
8.2K
24 января 2010 года
bagie2
299 / / 26.10.2008
а еще сдается мне using тоже виноват. вроде объект уничтожается раньше чем должен. надо еще проверить
8.2K
24 января 2010 года
bagie2
299 / / 26.10.2008
В общем наверное что-то в таком духе должно быть. Кстати я так и не понял зачем приложению посылать самому себе данные таким образом...

Код:
Thread udpserver = new Thread
                            (
                            delegate()
                            {
                                UdpClient udps = new UdpClient(7777);
                                IPEndPoint ipe = new IPEndPoint(IPAddress.Any, 0);

                                while (true)
                                {
                                    byte[] buffer = udps.Receive(ref ipe);
                                    Console.WriteLine("{0} bytes were received from {1}", buffer.Length, ipe.ToString());
                                    udps.Send(buffer, buffer.Length, ipe);
                                }

                                //Thread.CurrentThread.Abort();
                            }
                            );

            udpserver.IsBackground = true;
            udpserver.Start();

            byte[] buf = new byte[10];
 
            using (UdpClient udpc = new UdpClient())
            {
                udpc.Connect(new IPEndPoint(IPAddress.Loopback, 7777));
                IPEndPoint ipe = new IPEndPoint(IPAddress.Any, 0);

                for (int i = 0; i < 3; i++)
                {
                    udpc.Send(buf, buf.Length);

                    IAsyncResult ReceiveResult = udpc.BeginReceive(
                        delegate(IAsyncResult ar)
                        {
                            buf = udpc.EndReceive(ar, ref ipe);
                            Console.WriteLine("{0} bytes were received from {1}", buf.Length, ipe.ToString());
                        }, null);

                    while (!ReceiveResult.IsCompleted)
                    {
                        Application.DoEvents();
                        Thread.Sleep(50);
                    }
                }
            }

            Console.ReadKey();
            return;
268
24 января 2010 года
Михаил
587 / / 25.06.2005
приложение учебное, я так понимаю что принцип работы UdpClient не поменяется если его перенести в другой процесс или на другой хост.

то что вы предложили, это же самое, но только создается еще один поток для асинхронного вызова Receive или как оно реализовано в .net я не знаю, раньше создавался только один дополнительные поток для сервера и еще:
while (!ReceiveResult.IsCompleted)
{
Application.DoEvents();
Thread.Sleep(50);
}
имхо это нехорошо дергать поток только для проверки завершенности операции, ведь Receive специально блокирует поток до получения данных

вобщем вот так, это не то что хотелось бы получить
8.2K
24 января 2010 года
bagie2
299 / / 26.10.2008
Это не то же самое, потому что как я предложил: шлем блок данных и ждем когда он вернется. А как сделано у вас примерно выглядит так:

посылаем сразу 3 датаграммы
начинаем слушать. в тот момент, когда сервер получил, обработал и послал обратно, допустим, 2 пакета, и мы читаем данные, но сервер не успел обработать 3 пакет и нам пока больше получать нечего, поэтому поток выполняется дальше, уничтожает объект udpc из-за оператора using а тут сервер наконец обработал 3 часть данных и пытается их выслать, но соединение то закрыто... я вот так понял.
ну или проще если, то udpc.Available может быть 0, хотя данные мы еще не все получили или вообще не получали. вот и весь сказ.

Цитата:
Receive специально блокирует поток


Просто такой цикл позволит обработать очередь сообщений, например. Представьте, что этот код запихнули в метод нажатия кнопки... Пока данные не придут окно "повиснет". Хотя конечно в данном случае наверное и нет смысла делать так. Тем более метод DoEvents в консольном приложении (у меня прога с окошком)

268
25 января 2010 года
Михаил
587 / / 25.06.2005
более менее разобрался
Код:
Thread udpserver = new Thread
                (
                delegate()
                {
                    UdpClient udps = new UdpClient(new IPEndPoint(IPAddress.Loopback, 7777));
                    IPEndPoint ipe=new IPEndPoint(IPAddress.Any,0);

                    while (true)
                    {
                        byte[] buffer = udps.Receive(ref ipe);
                        Console.WriteLine("server: {0} bytes were received from {1}", buffer.Length, ipe.ToString());
                        udps.Send(buffer, buffer.Length, ipe);
                    }
                }
                );
            udpserver.IsBackground = true;
            udpserver.Name = "udpserver";
           
            //tcpserver.Start();
            udpserver.Start();

            Thread.CurrentThread.Name = "main";

            const int size = 1000;

            byte[] buf;
            int sent;

            using (UdpClient udpc = new UdpClient())
            {
                udpc.Connect(new IPEndPoint(IPAddress.Loopback, 7777));
                //udpc.Client.ReceiveBufferSize = 1024 * 1024;
                IPEndPoint ipe = new IPEndPoint(IPAddress.Any, 0);

                for (int i = 0; i < 3; i++)
                {
                    buf=new byte[size];
                    buf[0] = (byte)(i + 1);
                    buf[buf.Length - 1] = (byte)(i + 1);

                    IAsyncResult iar = udpc.BeginSend(buf, buf.Length,
                        delegate(IAsyncResult ar)
                        {
                            UdpClient udpca = (UdpClient)ar.AsyncState;
                            Console.WriteLine("client: {0} bytes sent", udpca.EndSend(ar));
                        },
                        udpc
                        );
                    iar.AsyncWaitHandle.WaitOne();
                }

                int asd = 3;
                while (asd-- > 0)
                {
                    Console.WriteLine(udpc.Available);
                    buf = udpc.Receive(ref ipe);
                    Console.WriteLine("client: 0: {2}, l-1:{3}; {0} bytes were received from {1}", buf.Length, ipe.ToString(), buf[0], buf[buf.Length - 1]);
                }
            }

            Console.WriteLine("\npress any key");
            Console.ReadKey();
            return;

на выделенном участке было while(udpc.Availabla>0), теперь вот так, и исключения пропали
каким образом udpc.Available влияет на происходящее?
у кого то еще появляются исключения?
268
26 января 2010 года
Михаил
587 / / 25.06.2005
соединение и на самом деле "закрывалось" когда использовалось Available, не все пакеты могли отправиться, потому и сокет выбрасывал исключение при попытке прочитать из него
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог