NetworkStream BeginRead читает только один раз? - PullRequest
0 голосов
/ 24 августа 2011

У меня есть довольно простой код, который читает строки из сетевого потока, к которому он подключается.В примере кода каждая читаемая строка содержит только одну строку, и она не продолжает получать больше от сервера.

Что не так?

        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;
            }
        }  

Ответы [ 3 ]

2 голосов
/ 24 августа 2011

Почему вы ожидаете, что он прочитает всю информацию в первую очередь?Я не эксперт, но мне кажется, что ни синхронный, ни асинхронный методы не гарантируют чтение всех данных (что бы это ни значило, поскольку, если сокет открыт, больше данных может поступать).После кода в вашем методе EndRead вам следует снова вызвать Read или BeginRead, если вы ожидаете больше данных.Вы должны знать, ожидается ли больше данных на основе протокола, который вы установили с клиентом.

1 голос
/ 24 августа 2011

Я столкнулся с похожими проблемами, когда разрабатывал tcp-приложения для встроенного устройства. В моем случае проблема заключалась в том, что устройство выдавало данные с задержкой и, следовательно, до того, как остальные данные могли поступить в элемент управления, переходит на следующую строку в программе, получая только исходные данные с сервера. Я обошел это, введя задержку.

Сразу после строки, в которой вы читаете данные с сервера, вводится задержка, и по этой причине было бы лучше запустить ее в отдельном потоке

thread.sleep(3000)

Скорее всего, это ваша проблема.

0 голосов
/ 24 августа 2011

возможно, ваш потоковый объект был удален, когда он вышел из области видимости, прежде чем readHandler мог быть вызван снова.попробуйте продвигать tcpClient и поток в область класса вместо области метода, или переместите чтение в отдельный поток, который завершается после завершения операции.

...