C #: поток прослушивателя UDP - PullRequest
8 голосов
/ 02 сентября 2010

Я хочу использовать UDP-сокеты для моей XNA-Networkgame.И сейчас я пытаюсь закодировать надежный поток прослушивания, но есть некоторые проблемы.

Если я использую сокет. Прием будет ждать до пакета.Это хорошо для моего слушателя.У моего потока есть цикл while, подобный следующему:

while(Listen == true)
{
    socket.Receive(...);
}

Но если я поменяю флаг прослушивания на false (если я хочу прекратить прослушивание), он застрянет в последнем .Receive ().

Затем я посмотрел на методы .BeginReceive ().Он вызовет метод, если пакет прибыл.Но для получения данных я должен использовать .EndReceive (), и с этим у меня проблема.Я все еще хочу прослушивать пакеты и не прекращать прослушивание, если пакет приходит.

Поэтому я все еще использую блокирующую версию с ".Receive ()".Я мог бы заставить поток прослушивания отменить вызов, вызвав: Thread.abort (), но это не очень хорошо.

В настоящее время я проверяю, доступны ли данные:

while(Listen == true)
{
    if(socket.Available > 0)
    {
        socket.Receive(...);
    }
}

Но я думаю, что этоэто не лучший способ ... Если вскоре после предложения if другой поток вызывает socket.Receive (..) он снова застрянет непреднамеренно.Нет ли способа отменить метод .Receive (..)?Я попытался установить тайм-аут, но если .Получить тайм-аут, он выдаст исключение ...

Я хочу простой поток прослушивания udp, я могу изящно остановиться.:-) В MSDN я не нашел пример слушателя, который прослушивает более одного пакета.Как справиться с этим другим программистом?

Ответы [ 2 ]

9 голосов
/ 02 сентября 2010

Отметьте флаг Listen как изменчивый, чтобы изменения могли быть видны между потоками.

public volatile bool Listen{get; set;}

Обработайте соответствующие исключения в вашей теме:

Thread listener = new Thread(()=>
{
    while(Listen == true)
    {
        try
        {
            socket.Receive();
        }
        catch(ThreadInterruptException)
        {
            break; // exit the while loop
        }
        catch(SocketException)
        { 
            break; // exit the while loop
        }
    }
});
listener.IsBackground = true;
listener.Start();

В коде, где вы переключаете флаг Listen на false, вы либо закрываете сокет, либо прерываете поток:

Listen = false;

socket.Shutdown(SocketShutdown.Both);
socket.Close();
//
// OR
//
listener.Interrupt();
1 голос
/ 03 сентября 2010

Спасибо, Лирик и Мэтт Дэвис. Это работает нормально, но нормально ли использовать исключения для этого? Я узнал, что исключения должны создаваться только в случае чего-то плохого / неожиданного. (для остановки предназначен метод блокировки :-))

Я обработал исключение, как это. Я ищу код ошибки и затем разрываю цикл.

                try
                {
                    broadcastSocket.ReceiveFrom(returnData, ref ep);

                    //...
                }
                catch (SocketException ex)
                {
                    if (ex.ErrorCode == 10004)
                    {
                        break;
                    }
                }

Почему я должен использовать

socket.Shutdown(SocketShutdown.Both);

до

socket.Close(); 

Не закроет ли .Close () также сокет?

И если я хочу снова использовать сокет, есть ли метод "Перезагрузка", или я должен создать новый экземпляр сокета?

Приветствие user437899

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...