2

非常に単純な TCP サーバーのコードを次に示します (基本的に、サンプルの非同期サーバー ソケットの例 - http://goo.gl/Ix5C - わずかに変更):

    public static void InitiateListener()
    {
        try
        {
            allDone = new ManualResetEvent(false);
            configFile = new XmlConfig();                
            StartListening();
        }
        catch (Exception exc)
        {
            LogsWriter f = new LogsWriter(configFile.ErrorLogsPath);
            f.WriteToFile(exc.Message);
            f.CloseFile();
        }

    }

    private static void StartListening()
    {      
        try
        {
            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, configFile.Port);
            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            listener.Bind(localEndPoint);
            listener.Listen(100);                

            while (true)
            {
                // Set the event to nonsignaled state.
                allDone.Reset();                    

                // Start an asynchronous socket to listen for connections.
                listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);

                // Wait until a connection is made before continuing.
                allDone.WaitOne();
            }
        }
        catch (Exception exc)
        {
            throw exc;
        }
    }

    public static void AcceptCallback(IAsyncResult ar)
    {
        allDone.Set(); // Signal the main thread to continue.               

        // Get the socket that handles the client request.
        Socket listener = (Socket)ar.AsyncState;
        Socket handler = listener.EndAccept(ar);

        // Create the state object.
        StateObject state = new StateObject();
        state.workSocket = handler;

        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
    }

    public static void ReadCallback(IAsyncResult ar)
    {
        string hexData = string.Empty;

        // Retrieve the state object and the handler socket from the asynchronous state object.
        StateObject state = (StateObject)ar.AsyncState;
        Socket handler = state.workSocket;

        try
        {
            // Read data from the client socket. 
            int bytesRead = handler.EndReceive(ar);                

            if (bytesRead > 0)
            {
                hexData = BitConverter.ToString(state.buffer);

                if (hexData.Contains("FA-F8")) //heartbeat - echo the data back to the client.
                {
                    byte[] byteData = state.buffer.Take(bytesRead).ToArray();
                    handler.Send(byteData);
                }
                else if (hexData.Contains("0D-0A")) //message
                {
                    state.AsciiData = Encoding.ASCII.GetString(state.buffer, 0, bytesRead);
                    state.ParseMessage(configFile);
                }
            }
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);                
        }
        catch (Exception)
        {
            handler.Shutdown(SocketShutdown.Both);
            handler.Close();
        }
    }

これはすべて Windows サービスにあります。CPU は、約 2 日半の実行後、完全に許容範囲内で 100% に達します。これは現在3回発生しています-Windowsサービスは常に正常に動作し、想定どおりに機能し、CPUリソースをほとんど使用しませんが、3日目には100%になり、サービスが再起動されるまでそこにとどまります.

非常に単純な CSV パケットを取得します。これをすばやく解析し、次のメソッドで Web サービスを介してデータベースに送信します CPU が 100% の場合でも、データベースはかなり確実にいっぱいになります。しかし、これは私が調査する必要がある場所の 1 つである可能性があることは理解していますか?

問題を引き起こしていると思われるコードの他の領域はどれですか? 非同期プログラミングは初めてなので、スレッドを手動で閉じる必要があるかどうかわかりません。また、これは別の問題である可能性があります: handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
ReadCallback 自体の中でその行を呼び出します。クライアントとの接続を維持し、データを受信し続けるためにこれを行いますが、ソケットを閉じて新しい接続を強制する必要がありますか?

いくつか提案をお願いできますか?ありがとう

4

2 に答える 2

0

while(true)startlistening メソッドでループする代わりに、呼び出す必要があります

listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);

新しいクライアントの受け入れが完了すると、AcceptCallback メソッドから。

于 2016-03-27T15:33:08.577 に答える