0

接続先のネットワーク ストリームから行を読み取る非常に単純なコードがあります。コード例では、1 行だけが読み取られ、サーバーからさらに取得することはありません。

なにが問題ですか?

        byte[] readBuffer = new byte[1024];
        byte[] tempBuff = new byte[1024];
        int tempBuffSize = 0;    


private void btnConnect_Click(object sender, EventArgs e)
            {

            TcpClient tcpClient = new TcpClient("192.168.1.151", 5505);
            NetworkStream stream = tcpClient.GetStream();
            stream.BeginRead(readBuffer, 0, 1024, readHandler, tcpClient); 
        }

void readHandler(IAsyncResult result)
        {
            TcpClient tcpClient = (TcpClient)result.AsyncState;
            int dataLen = tcpClient.GetStream().EndRead(result);

            int currStart = 0;
            int currEnd = -1;

            for (int i = 0; i < dataLen; i++)
            {
                if (readBuffer[i] == '\r' && i < (readBuffer.Length - 1) &&
                    readBuffer[i + 1] == '\n')
                {
                    // Set the end of the data 
                    currEnd = i - 1;

                    // If we have left overs from previous runs: 
                    if (tempBuffSize != 0)
                    {

                        byte[] joinedData = new byte[tempBuffSize + (currEnd - currStart + 1)];
                        Array.Copy(tempBuff, 0, joinedData, 0, tempBuffSize);
                        Array.Copy(readBuffer, currStart, joinedData, tempBuffSize, (currEnd - currStart + 1));

                        System.Text.Encoding enc = System.Text.Encoding.ASCII;
                        string myString = enc.GetString(joinedData);
                        System.Diagnostics.Debug.Write(myString);

                        tempBuffSize = 0;
                    }
                    else
                    {
                        System.Text.Encoding enc = System.Text.Encoding.ASCII;
                        string myString = enc.GetString(readBuffer);
                        System.Diagnostics.Debug.Write(myString);

                        // HandleData(readBuffer, currStart, currEnd);
                    }

                    // Set the new start - after our delimiter 
                    currStart = i + 2;
                }

            }

            // See if we still have any leftovers 
            if (currStart < dataLen)
            {
                Array.Copy(readBuffer, currStart, tempBuff, 0, dataLen - currStart);
                tempBuffSize = dataLen - currStart;
            }
        }  
4

3 に答える 3

2

そもそも、なぜ情報全体を読み取ることを期待しているのですか? 私は専門家ではありませんが、同期メソッドも非同期メソッドもすべてのデータを読み取ることを保証していないように思えます (ソケットが開いている限り、より多くのデータが到着する可能性があるため)。EndRead メソッドのコードの後で、さらにデータが必要な場合は、Read または BeginRead を再度呼び出す必要があります。クライアントで確立したプロトコルに基づいて、より多くのデータが予想されるかどうかを知っておく必要があります。

于 2011-08-24T11:39:56.350 に答える
1

組み込みデバイス用の tcp アプリを開発したときに、同様の問題に直面しました。私の場合、問題はデバイスが遅延時間内にデータを提供していたため、残りのデータが来る前に制御がプログラムの次の行に移動し、サーバーから最初のデータのみをフェッチすることでした。遅延を導入することでこれを回避しました。

サーバーからデータを読み取る行の直後に遅延が発生するため、これを別のスレッドで実行することをお勧めします

thread.sleep(3000)

これはおそらくあなたの問題です。

于 2011-08-24T11:29:35.330 に答える
0

readHandler が再度呼び出される前に、ストリーム オブジェクトがスコープ外になったときに破棄された可能性があります。tcpClient とストリームをメソッド スコープではなくクラス スコープに昇格してみるか、操作が終了したときに終了する別のスレッドに読み取りを移動してください。

于 2011-08-24T11:17:51.750 に答える