Как мне постоянно отслеживать новые TCP-клиенты? - PullRequest
3 голосов
/ 27 августа 2010

У меня есть TCP-сервер, который непрерывно асинхронно отслеживает новые входящие клиенты и добавляет их в список клиентов:

public class TcpServer
{
    public List<TcpClient> ClientsList = new List<TcpClient>();
    protected TcpListener Server = new TcpListener(IPAddress.Any, 3000);
    private _isMonitoring = false;

    public TcpServer()
    {
        Server.Start();
        Server.StartMonitoring();
    }

    public void StartMonitoring()
    {
        _isMonitoring = true;
        Server.BeginAcceptTcpClient(HandleNewClient, null);
    }

    public void StopMonitoring()
    {
        _isMonitoring = false;
    }

    protected void HandleNewClient(IAsyncResult result)
    {
        if (_isMonitoring)
        {
            var client = Server.EndAcceptTcpClient(result);
            ClientsList.Add(client);

            StartMonitoring(); // repeats the monitoring
        }
    }
}

Однако у меня есть две проблемы с этим кодом.

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

Второй флаг _isMonitoring. Я не знаю, как еще остановить асинхронный обратный вызов от активации и остановить его зацикливание. Любой совет, как это можно улучшить? Я бы хотел использовать асинхронные обратные вызовы и избегать необходимости вручную создавать новые потоки, в которых выполняются методы с циклами while (true).

1 Ответ

3 голосов
/ 27 августа 2010

По сути, ваша StartMonitoring функция должна быть зациклена - вы будете принимать только одного клиента за раз, а затем, как правило, передаете запрос рабочему потоку, а затем возобновляете прием новых соединений. Как написано, как вы сказали, он будет принимать только одного клиента.

Возможно, вы захотите расширить это в соответствии с вашими потребностями при запуске / завершении работы / прекращении работы, но в основном вы ищете StartMonitoring, чтобы быть более похожим на:

public void StartMonitoring()
{
    _isMonitoring = true;
    while (_isMonitoring)
        Server.BeginAcceptTcpClient(HandleNewClient, null);
}

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

...