0

私の非同期TCPクライアントサーバーアプリは今のところ機能しています。

しかし、CPU の高負荷の問題がいくつかあります。ネットワーク バッファを 8192 に設定すると、小さなメッセージには問題なく動作しますが、1MB を超える転送を行うと、CPU 負荷が非常に高くなります。バッファを 81920 に設定することで修正できます。

これを修正する解決策はありますか? 数 KB から数百 MB のデータを転送したい。

それぞれ異なるバッファサイズを持つ複数のTCP接続を持つことは良い考えですか? 他の解決策はありますか?

コードにパフォーマンス上の問題がある可能性もあります。

私の読み取りコード:

private class ReadClientState
    {
        public TcpClient Client { get; set; }
        public byte[] Buffer { get; set; } // buffer size...???

        public byte[] inc_message { get; set; }
        public int inc_message_size  { get; set; }
    }

BeginRead コールバック:

private void ReadCallback(IAsyncResult ar)
    {
        ReadClientState state = (ReadClientState)ar.AsyncState;
        int cbRead = 0;
        try
        {
            cbRead = state.Client.GetStream().EndRead(ar);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
            if (ex.InnerException is SocketException)
            {
                if (((SocketException)ex.InnerException).ErrorCode == 10054)
                {
                    ...
                }
            }
            return;
        }

// read 4 byte lenght header (new message incoming)
        if (state.inc_message_size == 0)
        {
            byte[] header = new byte[4];
            Buffer.BlockCopy(state.Buffer, 0, header, 0, 4);
            state.inc_message_size = BitConverter.ToInt32(header, 0);
        }

// copy buffer to message data array
        byte[] tmp = new byte[cbRead];
        Buffer.BlockCopy(state.Buffer, 0, tmp, 0, cbRead);
        state.inc_message = state.inc_message.Concat(tmp).ToArray();
        state.Buffer = new byte[bufferSize];


        Array.Clear(state.Buffer, 0, state.Buffer.Length);


// message is complete
        if (state.inc_message.Length >= state.inc_message_size)
        {
            if (state.inc_message.Length > state.inc_message_size)
            {
                Console.WriteLine("ERROR.. read more than expected");
            }
            else
            {
                Console.WriteLine("massage size: " + state.inc_message_size.ToString() + " total bytes read: " + state.inc_message.Length.ToString());

                Array.Clear(state.inc_message, 0, state.inc_message.Length);
                state.inc_message_size = 0;
            }
        }

        try
        {
            state.Client.GetStream().BeginRead(state.Buffer, 0, state.Buffer.Length, ReadCallback, state);
        }
        catch (Exception ex)
        {
            return;
        }
    }
4

0 に答える 0