Поток и TcpListener в C # - PullRequest
       5

Поток и TcpListener в C #

3 голосов
/ 18 января 2012

Мне нужно написать код, который использует TcpListener. Объект, использующий TcpListener, имеет 3 возможности: прослушивание, остановка прослушивания, отправка сообщения. Вот как выглядит мой код:

public class someClass
{
    public bool listenerEnable {get; set; }

    public void StartListen()
    {
        .
        .
        .

        while (listenerEnable)
        {
            // Block until client connected
            TcpClient client = server.AcceptTcpClient();       

            // code that doing something with the client message ... 
        }
    }
}

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

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

Спасибо за любую помощь.

Ответы [ 2 ]

3 голосов
/ 18 января 2012

Я бы предложил ждать события, а не ждать переменной. В вашей текущей схеме рассмотрите случай, когда ваш цикл проверяет, является ли переменная слушателя истинной. Если это так, он входит в цикл и ждет входящего соединения и блокируется. Так что теперь, даже если другой поток устанавливает переменную слушателя как false, ваш цикл не завершится, пока кто-то не подключится к нему и не обработает это соединение.

Одним из способов решения проблемы, описанной выше, будет следующий код:

WaitHandle[] waitHandles = new WaitHandle[] {endlLoopEvent};
while(true)
{
   int ret = WaitHandle.WaitAny(waitHandles, 100);
   if(WaitTimeout == ret) continue;
   else if(0 == ret) break; //our event has been signaled.
   else
    {
         if(!server.Pending()) continue; //Go back to the loop if no connection pending
         TcpClient client = server.AcceptTcpClient();  
         // You can spawn a thread to service the request.
    }
}

Отправка не повлияет на вышеприведенный цикл, при условии, что он не является ответом на запрос соединения выше.

2 голосов
/ 18 января 2012

Создать правильный, масштабируемый сервер сокетов непросто - я предлагаю вам найти / купить один - это было сделано много раз раньше.

Чтобы ответить на ваш вопрос, ваша проблема в том, что AcceptTcpClient являетсяблокировка вызова.Вы захотите использовать методы APM (модель асинхронного программирования), которые начинаются с BeginXXX и EndXXX, как MSDN BeginAcceptTcpClient .

Эти методы не блокируют потоки, но вы будетедолжен обрабатывать параллелизм.

...