61 / 61 / 15
Регистрация: 18.05.2015
Сообщений: 322
1

Никак не могу понять, как узнать, сколько байт читать из сокета

30.03.2016, 17:41. Показов 3572. Ответов 6
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Честно говоря, пишу не на C++, но вопрос этот может возникнуть в любом языке.
Вот, допустим, я пишу клиент к какому-то протоколу (не буду говорить, к какому, а то сразу посоветуют готовую библиотеку и обсуждение закончится), который коннектится по TCP, Отправляет какие-то данные и должен получить в ответ от сервера данные. При этом данные получаются в формате, похожем на XML и они не оканчиваются CRLF или вообще чем-то особенным, просто идет ">" в конце последнего тега, но, т.к. там есть вложенные теги, понятно, что ориентироваться на них нельзя.
Я не знаю, сколько именно данных приходит, но должен получить их все (довольно логично). Можно ли как-то узнать, сколько там данных пришло в ответ?

Самое лучшее, до чего я додумался - это в цикле читать с таймаутом по одному байту, но это получается очень неэффективно и в конце подвисает на таймаут (что логично).

Все вопросы подобного рода связаны с сервер сайд (ощущение, что народ во всем мире только отправляет данные, а что приходит в ответ уже никто не смотрит).
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.03.2016, 17:41
Ответы с готовыми решениями:

Не могу никак понять как делать
1) Создайте новое консольное приложение для решения задачи. Объявите вещественную переменную x....

Никак не могу понять как рассуждать в задачи
В 350 сельских населённых пунктах области проживает 1200 участников ВОВ. Какова вероятность того,...

Как узнать, сколько байт прочитано?
std::ifstream Options; Options.open("Options.SculptorOptions", std::ios::binary); ...

НовичОк в Scilab - никак не могу понять как записать правильно формулы. Постоянно путаюсь в скобках
Уважаемые форумчане. Помогите новичку разобраться с формулами. Начал изучать SCIlab, но никак не...

6
Native x86
Эксперт Hardware
5451 / 3238 / 929
Регистрация: 13.02.2013
Сообщений: 10,296
30.03.2016, 17:44 2
Реализуйте простейший протокол приложения, который передает сначала размер пакета (первые четыре байта), а потом и сами данные. Этим вы заодно решите проблему склейки отправленных друг за другом пакетов.
0
61 / 61 / 15
Регистрация: 18.05.2015
Сообщений: 322
30.03.2016, 18:50  [ТС] 3
Цитата Сообщение от quwy Посмотреть сообщение
Реализуйте простейший протокол приложения, который передает сначала размер пакета (первые четыре байта), а потом и сами данные. Этим вы заодно решите проблему склейки отправленных друг за другом пакетов.
Протокол уже реализован, в том-то и дело, что я не могу повлиять на имплементацию сервера, иначе я бы просто установил какую-нибудь управляющую последовательность, которая должна стоять в конце.
Протокол - XMPP, но вопрос не в нем конкретно, а как в принципе это делается.
0
Native x86
Эксперт Hardware
5451 / 3238 / 929
Регистрация: 13.02.2013
Сообщений: 10,296
30.03.2016, 19:00 4
В принципе, есть функции ioctl() и ioctlsocket() и параметр FIONREAD, который вернет вам количество байт, уже ожидающих в приемном буфере.
0
322 / 170 / 24
Регистрация: 25.03.2012
Сообщений: 712
30.03.2016, 21:53 5
Лучший ответ Сообщение было отмечено klopik как решение

Решение

Цитата Сообщение от klopik Посмотреть сообщение
Все вопросы подобного рода связаны с сервер сайд (ощущение, что народ во всем мире только отправляет данные, а что приходит в ответ уже никто не смотрит).
Это вопросы обеих сторон ... это вопросы TCP.
В TCP нет "пакетов" - вы можете отправлять по 20 байт, а получать за одно чтение и 5 байт и 30..
TCP - это поток, труба, куда в один конец вливаются байты, а из другого они вытекают.

Подавляющее большинство сетевых протоколов (HTTP, SIP, и др.) на уровне выше транспортного используют фиксированный разделитель сообщений. Обычно это "\n\n" - пустая строка.

Иногда перед сообщением (чаще бинарным) следует его последующая длина в фиксированном числе байт (часто 2). Это другой способ, но реже употребляемый.

В любом случае, поток TCP приходится читать побайтно. А чтобы это реально не делать, добавляется промежуточный уровень буферизации, когда читается в фиксированный буфер "сколько дадут" (это не предсказуемо!), а оттуда уже выгребается побайтно. Всё это замечательно описано в книгах Р.Стивенса.
Или см. Сетевое программирование в Linux (там есть примеры кода).
2
61 / 61 / 15
Регистрация: 18.05.2015
Сообщений: 322
31.03.2016, 13:54  [ТС] 6
Кажется, я придумал решение, во всяком случае, оно должно подходить для XMPP и других подобных протоколов.
Решение заключается в том, чтобы читать побайтно из сокета (как советуют выше) до возникновения ошибки либо до появления определенной конструкции в строке. Например, первый ответ от jabber-сервера по нормальному должен оканчиваться закрывающим тегом "</stream:features>", соответственно, мой код ожидает появления этого тега и, если он встретился, чтение заканчивается. Ну и при ошибке (таймаут) также происходит завершение цикла.
0
322 / 170 / 24
Регистрация: 25.03.2012
Сообщений: 712
31.03.2016, 17:14 7
Цитата Сообщение от klopik Посмотреть сообщение
Решение заключается в том, чтобы читать побайтно из сокета (как советуют выше) до возникновения ошибки либо до появления определенной конструкции в строке.
Только для этого не нужно читать из сокета побайтно (очень уж накладно дёргать ОС за каждым байтом).
- Вы можете читать свои байты из промежуточного буфера достаточно большой длины ... скажем 1500 байт
- а если указатель читаемого байта дощёл до конца буфера, то запрашивать чтение полной длины, те же 1500 байт
- получите реально доступные в сокете данные ... 55 байт, например
- переустановите указатель на начало буфера и снова дёргаете по одому байту...
0
31.03.2016, 17:14
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
31.03.2016, 17:14
Помогаю со студенческими работами здесь

Никак не могу понять
Есть 2 консольных проекта в 1 стоит ссылка на второй. // первый using System; using...

Maple, никак не могу понять
не могу понять как нарисовать график так чтоб он рисовал массив. ну или как сделать из массива...

Не могу никак понять (новичек).
Здравствуйте, необходимо найти сумму квадратов четных чисел в интервале заданном значениями...

никак не могу понять задачу
Задали действительную квадратную матрицу A размером N*M. Найти сумму елементов главной и сторонней...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru