C # Async Socket, метод BeginReceive не запускает новый поток - PullRequest
0 голосов
/ 27 сентября 2018

У меня есть прослушиватель сокетов асинхронного сервера и тысячи клиентов.
Приведенный ниже код работает, как и ожидалось, до некоторого времени (который отличается, иногда 1 час, иногда 3 дня), затем не принимает новые подключения.Когда это событие происходит, мой процесс все еще работает, и порт, который сервер прослушивает, показывая все еще прослушивающий Мониторинг ресурсов.Я использую wireshark для определения клиентских подключений в этот период.

Поэтому я добавляю несколько журналов, чтобы найти причину, почему?Я кеширую некоторые вещи, но я не знаю, что это вызывает.Я обнаружил, что BeginReceive не запускает новый поток, а текущий поток продолжает работать по моему OnClientConnected методу.Поэтому сервер не принимает новые подключения.

    protected Socket listener;
    protected ManualResetEvent acceptDone = new ManualResetEvent(false);

    public void Start(int port) {
        try {
            var ipEndPoint = new IPEndPoint(IPAddress.Any, port);
            listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
            LingerOption myOpts = new LingerOption(false, 0);
            listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, myOpts);
            listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true);

            listener.Bind(ipEndPoint);
            listener.Listen(100000);
            Logger.Info(
                $"{ServiceInformation.LocalIpAddress}:{port} listining.");
            StartListening();
        } catch (Exception e) {
            Logger.Error(
                $"{ServiceInformation.LocalIpAddress}:{port} not listening.",
                e);
        }
    }

    private void StartListening() {
        try {
            while (true) {
                try {
                    Logger.Info("StartListening acceptdone reset." + Thread.CurrentThread.ManagedThreadId);
                    acceptDone.Reset();

                    Logger.Info("StartListening begin accept." + Thread.CurrentThread.ManagedThreadId);
                    listener.BeginAccept(OnClientConnected, listener);

                    Logger.Info("StartListening acceptdone waitone." + Thread.CurrentThread.ManagedThreadId);
                    acceptDone.WaitOne();
                } catch (Exception e) {
                    Logger.Error("StartListening error." + Thread.CurrentThread.ManagedThreadId, e);
                }
            }
        } catch (Exception e) {
            Logger.Error("while error" + Thread.CurrentThread.ManagedThreadId, e);
        }
    }

    protected void OnClientConnected(IAsyncResult asyncResult) {
        acceptDone.Set();
        Logger.Info("OnClientConnected acceptdone set." + Thread.CurrentThread.ManagedThreadId);
        //I am expecting here to changing current thread id. If it change my listener working. 

        Socket client;
        try {
            var _listener = (Socket)asyncResult.AsyncState;
            client = _listener.EndAccept(asyncResult);
            Logger.Info($"Client connected: {client.RemoteEndPoint}" + Thread.CurrentThread.ManagedThreadId);
        } catch (ObjectDisposedException) {
            Logger.Error($"Listening socket has been closed." + Thread.CurrentThread.ManagedThreadId);
            return;
        }

        try {
            var state = GetStateObject(client);

            client.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, OnMessageReceived, state);
        } catch (Exception e) {
            Logger.Error($"Listening socket has been closed.", e);
            client.Shutdown(SocketShutdown.Both);
            client.Close();
        }
        Logger.Info("OnClientConnected finish.");
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...