1

メモリ使用量が驚くほど増加するだけでなく、受信終了時に「既存の接続がリモート ホスト 10054 によって閉じられました」というメッセージが表示され、pgm が停止します。助けてください
ありがとう

TCP ソケット サーバーを使用していますが、問題なく動作します。ただし、作業メモリは 10 MB から 250 MB に増加します。

close_wait ソケットの nestat を監視しましたが、何も見つかりませんでしたか?

誰でも私を助けてください。メモリリークなしで多くの接続を処理する必要があります。

StartListen のコード

void StartListen(object sender, System.EventArgs e)
{
    try
    {
        string portStr = textBoxPort.Text;
        int port = System.Convert.ToInt32(portStr);
        // Create the listening socket...
        m_mainSocket = new Socket(AddressFamily.InterNetwork,
            SocketType.Stream,
            ProtocolType.Tcp);
        IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, port);

        m_mainSocket.Bind(ipLocal);

        m_mainSocket.Listen(100);

        m_mainSocket.BeginAccept(new AsyncCallback(OnClientConnect),null);

        UpdateControls(true);
    }
    catch (SocketException se)
    {
        writer.WriteToLog("In StartListen " + se.Message);
    }
}

public void OnClientConnect(IAsyncResult asyn)
{
    try
    {
        Socket m_mainSocket = (Socket)asyn.AsyncState;

        Socket workerSocket = m_mainSocket.EndAccept(asyn);
        Interlocked.Increment(ref m_clientCount);

        m_workerSocketList.Add(workerSocket);

        WaitForData(workerSocket, m_clientCount);

        m_mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null);
    }
    catch (ObjectDisposedException)
    {
        System.Diagnostics.Debugger.Log(0, "1", "\n OnClientConnection: Socket has been closed\n");
    }
    catch (Exception se)
    {
        writer.WriteToLog(DateTime.Now.ToString() + " OnClientConnect " + se.Message);
    }
}

public void OnDataReceived(IAsyncResult asyn)
{
    // Logger.Log("In OnDataReceived");
    SocketPacket socketData = (SocketPacket)asyn.AsyncState;
    bool socketClosed = false;


    try
    {
        // Complete the BeginReceive() asynchronous call by EndReceive() method
        // which will return the number of characters written to the stream 
        // by the client
        int iRx = socketData.m_currentSocket.EndReceive(asyn);
        char[] chars = new char[iRx + 1];
        // Extract the characters as a buffer
        System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
        int charLen = d.GetChars(socketData.dataBuffer,
            0, iRx, chars, 0);




        System.String szData = new System.String(chars);
            szData= szData.TrimEnd('\0');




             if (!SocketExtensions.IsConnected(socketData.m_currentSocket)) {

            socketData.m_currentSocket.Shutdown(SocketShutdown.Both);
            socketData.m_currentSocket.Close();
                              return;
               } 

        else
        {

            WaitForData(socketData.m_currentSocket, socketData.m_clientNumber);
        }
    }
    catch (ObjectDisposedException)
    {
        System.Diagnostics.Debugger.Log(0, "1", "\nOnDataReceived: Socket has been closed\n");
    }
    catch (SocketException se)
    {
        if (se.ErrorCode == 10054) // Error code for Connection reset by peer
        {
            string msg = "Client " + socketData.m_clientNumber + " Disconnected" + "\n";

            // Remove the reference to the worker socket of the closed client
            // so that this object will get garbage collected
            m_workerSocketList[socketData.m_clientNumber - 1] = null;
            UpdateClientListControl();
        }
        else
        {
            MessageBox.Show(se.Message);
           // Logger.Log(se.Message);
            writer.WriteToLog("OnDataReceived " + se.Message);

        }
    }
    catch (Exception ex)
    {
       // Logger.Log(ex.Message);
        writer.WriteToLog("OnDataReceived " + ex.Message);
    }
}
static class SocketExtensions
{
    public static bool IsConnected(this Socket socket)
    {
        try
        { 
            return !(socket.Poll(1, SelectMode.SelectRead) && socket.Available == 0);
        }
        catch (SocketException) { return false; }
    }
}
4

1 に答える 1

0

.NET アプリのメモリ フットプリントが一定のサイズまで増加しても、それが増加し続けない限り、問題はありません。ワークロードに応じて、TCP サーバーは新しいクライアントを受け入れるたびに多くのオブジェクトを割り当て、データを送受信します。それらが使用されなくなった後でも、これらのオブジェクトは GC が解放するまでしばらくメモリに残ります。これは、メモリ リークがあるという意味ではありません。

メモリ使用量が増えすぎてシステム メモリの問題が発生している場合は、クライアント リクエストの処理中に作成されたオブジェクトを保持していないことを確認してください。

于 2012-09-13T07:37:02.060 に答える