Серверный сокет C # перестает принимать новые подключения - PullRequest
0 голосов
/ 28 мая 2018

Я написал перехватчик TCP-сокета на основе сокета сервера и событий для перевода перехваченных соединений на высокий уровень.

public class TcpCatcher
{
    private static readonly Exception IsStartedException = new Exception("Catcher has already been started.");

    private int _port;
    private int _openTimeout;

    private Socket _serverSocket;
    private SocketAsyncEventArgs _acceptAsyncArg;


    public int Port
    {
        get => _port;
        set
        {
            if (IsStarted)
                throw IsStartedException;
            _port = value;
        }
    }

    public int OpenTimeout
    {
        get => _openTimeout;
        set
        {
            if (IsStarted)
                throw IsStartedException;
            _openTimeout = value;
        }
    }

    public bool IsStarted { get; protected set; }

    public event Action<Socket> ConnectionCatched;
    public event Action<string> Log;

    public TcpCatcher()
    {
        _acceptAsyncArg = new SocketAsyncEventArgs();
        _acceptAsyncArg.SetBuffer(null, 0, 0);
        _acceptAsyncArg.Completed += OnAcceptSocket;
    }

    private void OnLog(string message)
    {
        if (Log != null)
            Log(message);
    }

    private void AcceptSocket()
    {
        OnLog("AcceptSocket is executing");
        bool isAsync;

        do
        {
            isAsync = _serverSocket.AcceptAsync(_acceptAsyncArg);

            if (!isAsync)
            {
                OnLog($"AcceptAsync finished Sync.");
                if (_acceptAsyncArg.SocketError == SocketError.Success)
                    ConnectionCatched(_acceptAsyncArg.AcceptSocket);
            }
        } while (!isAsync);
        OnLog("AcceptSocket finished");
    }

    private void OnAcceptSocket(object sender, SocketAsyncEventArgs asyncArg)
    {
        OnLog("Caught new socket!");

        if (asyncArg.SocketError != SocketError.Success)
        {
            OnLog($"Socket has bad status:${asyncArg.SocketError}");
            asyncArg.AcceptSocket?.Close();
        }
        else
        {
            ConnectionCatched(asyncArg.AcceptSocket);
        }

        OnLog($"Caught socket was processed");
        asyncArg.AcceptSocket = null;

        if (IsStarted)
            AcceptSocket();
    }

    public void Start()
    {
        OnLog($"Starting");
        IsStarted = true;
        _serverSocket?.Close();
        _serverSocket = new Socket(SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
        _serverSocket.Bind(new IPEndPoint(IPAddress.Any, Port));
        _serverSocket.Listen((int)SocketOptionName.MaxConnections);
        AcceptSocket();

    }

    public void Finish()
    {
        OnLog($"Stopping");
        _serverSocket.Disconnect(false);
        _serverSocket.Close();
        _serverSocket.Dispose();
        _serverSocket = null;
        IsStarted = false;
    }
}

Улавливатели используются в службе Windows и инициализируются при запуске службы.Они работают около 2-4 дней и останавливаются по неизвестным причинам, принимая розетки один за другим.Можете ли вы объяснить, почему это может быть и как эта проблема может быть решена?

...