Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Сети > чтение дефрагментированных пакетов через сокет |
Автор: Cyr 10.2.2015, 14:03 |
открываем сокет: s=socket(AF_INET, SOCK_STREAM, 0) читаем в бесконечном цикле из сокета: nbytes=recv(s, buf, sizeof(buf), 0); правильный пакет будет иметь формат: 0, [количество байтов], [сами байты...]. проблемма в том, что пакеты могут рваться в влюбом месте. и продолжаться в следующем пакете. помогите правильно собрать пакет из фрагментов. |
Автор: Cyr 10.2.2015, 16:10 | ||
|
Автор: feodorv 10.2.2015, 17:02 | ||
Здесь из vbuf копируются данные в buf (а не наоборот). Самих данных может накопиться много, что гарантирует выход за пределы массива. И второе чтение из сокета может не заполнить пакет до конца. Отсутствует обработка ошибок. Само попакетное чтение из сокета можно организовать так:
При этом buf должен быть размером не менее 255+2 байт (чтобы гарантировано влез любой пакет). |
Автор: Cyr 11.2.2015, 10:33 | ||
feodorv, Спасибо большое. vbuf - это временный буфер. Поэтому всё правильно. Размер пакета не может превышать 2+240 байт. Это ограничение АТС, которая шлёт пакеты (прописано в её документации). И на практике пакет никогда не рвался более чем на 2 части. Поэтому я и сделал так в своём примере. Вопросик по этим проверкам:
В TCP потоке могут быть испорченные пакеты? И можно ли процедурку сделать только в один цикл, а не в 2 ? |
Автор: feodorv 11.2.2015, 19:03 |
Практика - вещь тонкая, а где тонко, там и рвется. 100%ю гарантию от большего числа разрывов она не даст, а переписать 2 последовательных чтения из сокета в один компактный цикл (который вдобавок читает из сокета попакетно, без лишних байт) - дело несложное))) Ну, лишние 16 байт погоды не сделают, а вот защиту от переполнения буфера обеспечат. Бывает всякое. Но в данном случае скорее стоит защита от программных ошибок (как со стороны устройства, так и с нашей стороны). Например, мы можем ошибочно считать из сокета лишнее или наоборот. Согласно протоколу (прикладного уровня) первый байт в пакете должен быть нулем, так что нам стоит это проверить? А если не ноль, то протокол каким-то образом заблудился, нужно переустанавливать соединение с устройством. А это принципиально? Первый цикл считывает 2 байта из сокета, цикл нужен, если внезапно доступен только один байт, а второго нужно ждать. В общем, можно первый цикл заменить на 2 последовательных чтения по одному байту с проверкой ошибок при каждом чтении. Сами циклы в коде сделаны однотипно, для лучшего понимания))) |
Автор: feodorv 12.2.2015, 18:36 | ||||
С каким точно?))) Не минус ли 2? А какой errno?
Эх, а там есть ошибка, должно быть:
|
Автор: Cyr 13.2.2015, 09:21 |
Ну вот. Спасибо. |