powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / NetworkStream.Read как читать кусками?
17 сообщений из 17, страница 1 из 1
NetworkStream.Read как читать кусками?
    #39003375
Winnipuh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как читать кусками и вернуть в конце массив байтов?

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
int numberOfBytesRead = 0;
                int numberOfBytesReadTotal = 0;

                do
                {
                    numberOfBytesRead = tcpClient.GetStream().Read(myReadBuffer, 0, myReadBuffer.Length);
                    //?
                    numberOfBytesReadTotal += numberOfBytesRead;
                }
                while (tcpClient.GetStream().DataAvailable);
//?
...
Рейтинг: 0 / 0
NetworkStream.Read как читать кусками?
    #39003411
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Winnipuh,

1) Не нужно постоянно делать tcpClient.GetStream(). Достаточно один раз получить его.
2) do while - неправильно. Потому что при первой итерации DataAvailible может быть и false. И вообще - странный маркер окончания данных. Я бы сказал, что это вообще не маркер.
3) по сути вопроса: пишем все считанные куски в MemoryStream и в конце пользуемся ToArray
...
Рейтинг: 0 / 0
NetworkStream.Read как читать кусками?
    #39003442
Winnipuh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79Winnipuh,

1) Не нужно постоянно делать tcpClient.GetStream(). Достаточно один раз получить его.
2) do while - неправильно. Потому что при первой итерации DataAvailible может быть и false. И вообще - странный маркер окончания данных. Я бы сказал, что это вообще не маркер.
3) по сути вопроса: пишем все считанные куски в MemoryStream и в конце пользуемся ToArray

Так сделал, исходя из примера

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
   
        public byte[] ReceiveResponseRaw()
        {
            byte[] bRet = null;

            NetworkStream stream = tcpClient.GetStream();
            if (stream.CanRead)
            {
                byte[] myReadBuffer = new byte[1024];
                using (var memStream = new MemoryStream())
                {
                    while (stream.DataAvailable)
                    {
                        int numberOfBytesRead = 0;
                        numberOfBytesRead = stream.Read(myReadBuffer, 0, myReadBuffer.Length);
                        memStream.Write(myReadBuffer, 0, numberOfBytesRead);
                    }
                    bRet = memStream.ToArray();
                }
            }
            return bRet;
        }
...
Рейтинг: 0 / 0
NetworkStream.Read как читать кусками?
    #39003454
Winnipuh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
не, все-таки предыдущий вариант неправильный, после нескольких чтений стримов что-то криво, вернул do-while, так работает.


Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
        public byte[] ReceiveResponseRaw()
        {
            byte[] bRet = null;

            NetworkStream stream = tcpClient.GetStream();
            if (stream.CanRead)
            {
                byte[] myReadBuffer = new byte[1024];
                using (var memStream = new MemoryStream())
                {
                    do
                    {
                        int numberOfBytesRead = 0;
                        numberOfBytesRead = stream.Read(myReadBuffer, 0, myReadBuffer.Length);
                        memStream.Write(myReadBuffer, 0, numberOfBytesRead);
                    } while (stream.DataAvailable);

                    bRet = memStream.ToArray();
                }
            }
            return bRet;
        }
...
Рейтинг: 0 / 0
NetworkStream.Read как читать кусками?
    #39003476
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79Потому что при первой итерации DataAvailible может быть и false.
Может быть и не при первой - при том, что отдающая сторона продолжает заливать данные. Флуктуации сетевой передачи, и типа всё такое. Нужно проверять DataAvailable в цикле на протяжении определенного таймаута.
...
Рейтинг: 0 / 0
NetworkStream.Read как читать кусками?
    #39003537
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры ПавловныArm79Потому что при первой итерации DataAvailible может быть и false.
Может быть и не при первой - при том, что отдающая сторона продолжает заливать данные. Флуктуации сетевой передачи, и типа всё такое. Нужно проверять DataAvailable в цикле на протяжении определенного таймаута.

Ну да, я и не спорю. Проверять нужно в цикле.
WinnipuhArm79Winnipuh,

1) Не нужно постоянно делать tcpClient.GetStream(). Достаточно один раз получить его.
2) do while - неправильно. Потому что при первой итерации DataAvailible может быть и false. И вообще - странный маркер окончания данных. Я бы сказал, что это вообще не маркер.
3) по сути вопроса: пишем все считанные куски в MemoryStream и в конце пользуемся ToArray

Так сделал, исходя из примера

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
   
        public byte[] ReceiveResponseRaw()
        {
            byte[] bRet = null;

            NetworkStream stream = tcpClient.GetStream();
            if (stream.CanRead)
            {
                byte[] myReadBuffer = new byte[1024];
                using (var memStream = new MemoryStream())
                {
                    while (stream.DataAvailable)
                    {
                        int numberOfBytesRead = 0;
                        numberOfBytesRead = stream.Read(myReadBuffer, 0, myReadBuffer.Length);
                        memStream.Write(myReadBuffer, 0, numberOfBytesRead);
                    }
                    bRet = memStream.ToArray();
                }
            }
            return bRet;
        }



Неправильно. Для начала определитесь, что считать окончанием передачи. Флаг DataAvailible лишь показывает, существуют ли на момент опроса доступные данные, не более того.
...
Рейтинг: 0 / 0
NetworkStream.Read как читать кусками?
    #39003545
Winnipuh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
как определиться?
пока есть данные я читаю.
Если будет false - не читаю, а что делать
...
Рейтинг: 0 / 0
NetworkStream.Read как читать кусками?
    #39003702
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Winnipuhкак определиться?
пока есть данные я читаю.
Если будет false - не читаю, а что делать
Пример: Вы знаете, что получаете строку длиной 1000 байт. Но в вашем цикле получили только 600 и DataAvailable равен false. Нужно ли прекращать обработку? Очевидно, что нет. В данном случае маркером окончания передачи является получение 1000 байтов.

Грубо получится так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
stream = tcpclient.getstream();
memorystream = new memorystream();  <-- тут не забываем про dispose

while (1000 > memorystream.length) {
  if timeout
     throw new TimeoutException();

  if false == stream.DataAvailable {
     Thread.Sleep(1);
     continue;
  }

  readedCount = stream.Read(buffer);
  memorystream.write(buffer, 0, readedCount);
  обнуляем таймаут;
}

var result = memorystream.ToArray();
memorystream.dispose();

return result;
...
Рейтинг: 0 / 0
NetworkStream.Read как читать кусками?
    #39003734
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TcpClient - кривой.

если передающая сторона закроет сокет,
DataAvailable - вернёт false, при этом Read вернёт 0
...
Рейтинг: 0 / 0
NetworkStream.Read как читать кусками?
    #39003790
Winnipuh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилTcpClient - кривой.

если передающая сторона закроет сокет,
DataAvailable - вернёт false, при этом Read вернёт 0


Да, на больших ответах видно, что кривой, читает какими-то неопределнными кусками. Наверняка и сервер отдает как хочет, но чтение идет кусками.

Так что делать, как правильно читать?
...
Рейтинг: 0 / 0
NetworkStream.Read как читать кусками?
    #39003805
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WinnipuhТак что делать, как правильно читать?
из самих данных - можешь длину определить?
...
Рейтинг: 0 / 0
NetworkStream.Read как читать кусками?
    #39003817
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WinnipuhТак что делать, как правильно читать?
Я честно говоря не понимаю, в чем проблема моих объяснений? Если вы знаете, что за данные вам сыпятся, то должны знать как отличать один пакет от другого.

Существует 2 популярных пути - один заключается в предварительной передаче длины последующего сообщения. Второй - по окончании пакета данных передается какой то маркер.

Например, для POP3 протокола маркером окончания однострочного ответа на команду являются \r\n
Для протокола FIX там жесткая комбинация из длины вначале, и контрольных сумм в конце.
...
Рейтинг: 0 / 0
NetworkStream.Read как читать кусками?
    #39003867
Winnipuh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79WinnipuhТак что делать, как правильно читать?
Я честно говоря не понимаю, в чем проблема моих объяснений? Если вы знаете, что за данные вам сыпятся, то должны знать как отличать один пакет от другого.

Существует 2 популярных пути - один заключается в предварительной передаче длины последующего сообщения. Второй - по окончании пакета данных передается какой то маркер.

Например, для POP3 протокола маркером окончания однострочного ответа на команду являются \r\n
Для протокола FIX там жесткая комбинация из длины вначале, и контрольных сумм в конце.

Мопед Сервер не мой. Я читаю из Redis, у них протокол открыт.

Я ваш подход использовал, делаю спячку по 1-2 мс, работает правильно на больших данных.
Длину в принципе можно узнать, она идет вначале.
...
Рейтинг: 0 / 0
NetworkStream.Read как читать кусками?
    #39003870
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WinnipuhДлину в принципе можно узнать, она идет вначале.
не в принципе а в корпусе нужно знать. соединение может закрыться преждевременно - потерю данных - не отследить будет
...
Рейтинг: 0 / 0
NetworkStream.Read как читать кусками?
    #39003887
Winnipuh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилWinnipuhДлину в принципе можно узнать, она идет вначале.
не в принципе а в корпусе нужно знать. соединение может закрыться преждевременно - потерю данных - не отследить будет

Если есть данные то они идут так

Код: c#
1.
2.
3.
36 52 48 55 50 57 50 13 10

$407292\r\n



то есть - данные далее и длина их такая. Далее можно дочитывать.
Но, если этот кусок оборвётся, тогда п-ц, разве что дотягивать до признака \r\n
...
Рейтинг: 0 / 0
NetworkStream.Read как читать кусками?
    #39003893
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Winnipuh,

ждать в течение таймаута, если не дождался - повторять запрос, или не повторять
...
Рейтинг: 0 / 0
NetworkStream.Read как читать кусками?
    #39003896
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WinnipuhНо, если этот кусок оборвётся, тогда п-ц, разве что дотягивать до признака \r\n
сюр какой-то.
Если не удалось прочитать длину - значит закрыть соединение и всё сначала ("длина" ещё 0 и -1 бывает)
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / NetworkStream.Read как читать кусками?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]