|
Модераторы: feodorv |
|
Cyr |
|
|||
Новичок Профиль Группа: Участник Сообщений: 48 Регистрация: 20.3.2006 Репутация: нет Всего: нет |
открываем сокет:
s=socket(AF_INET, SOCK_STREAM, 0) читаем в бесконечном цикле из сокета: nbytes=recv(s, buf, sizeof(buf), 0); правильный пакет будет иметь формат: 0, [количество байтов], [сами байты...]. проблемма в том, что пакеты могут рваться в влюбом месте. и продолжаться в следующем пакете. помогите правильно собрать пакет из фрагментов. |
|||
|
||||
Cyr |
|
|||
Новичок Профиль Группа: Участник Сообщений: 48 Регистрация: 20.3.2006 Репутация: нет Всего: нет |
|
|||
|
||||
feodorv |
|
|||
Эксперт Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
Здесь из vbuf копируются данные в buf (а не наоборот). Самих данных может накопиться много, что гарантирует выход за пределы массива. И второе чтение из сокета может не заполнить пакет до конца. Отсутствует обработка ошибок. Само попакетное чтение из сокета можно организовать так:
При этом buf должен быть размером не менее 255+2 байт (чтобы гарантировано влез любой пакет). Это сообщение отредактировал(а) feodorv - 10.2.2015, 17:06 -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
Cyr |
|
|||
Новичок Профиль Группа: Участник Сообщений: 48 Регистрация: 20.3.2006 Репутация: нет Всего: нет |
feodorv,
Спасибо большое. vbuf - это временный буфер. Поэтому всё правильно. Размер пакета не может превышать 2+240 байт. Это ограничение АТС, которая шлёт пакеты (прописано в её документации). И на практике пакет никогда не рвался более чем на 2 части. Поэтому я и сделал так в своём примере. Вопросик по этим проверкам:
В TCP потоке могут быть испорченные пакеты? И можно ли процедурку сделать только в один цикл, а не в 2 ? Это сообщение отредактировал(а) Cyr - 11.2.2015, 11:13 |
|||
|
||||
feodorv |
|
|||
Эксперт Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
Практика - вещь тонкая, а где тонко, там и рвется. 100%ю гарантию от большего числа разрывов она не даст, а переписать 2 последовательных чтения из сокета в один компактный цикл (который вдобавок читает из сокета попакетно, без лишних байт) - дело несложное))) Ну, лишние 16 байт погоды не сделают, а вот защиту от переполнения буфера обеспечат. Бывает всякое. Но в данном случае скорее стоит защита от программных ошибок (как со стороны устройства, так и с нашей стороны). Например, мы можем ошибочно считать из сокета лишнее или наоборот. Согласно протоколу (прикладного уровня) первый байт в пакете должен быть нулем, так что нам стоит это проверить? А если не ноль, то протокол каким-то образом заблудился, нужно переустанавливать соединение с устройством. А это принципиально? Первый цикл считывает 2 байта из сокета, цикл нужен, если внезапно доступен только один байт, а второго нужно ждать. В общем, можно первый цикл заменить на 2 последовательных чтения по одному байту с проверкой ошибок при каждом чтении. Сами циклы в коде сделаны однотипно, для лучшего понимания))) -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
Cyr |
|
|||
Новичок Профиль Группа: Участник Сообщений: 48 Регистрация: 20.3.2006 Репутация: нет Всего: нет |
У меня из вашей подпрограммы иногда происходит выход с кодом меньше 0. Подозрение на то, что nbytes = recv( s, buf, 2, 0) читает только один байт, и выдаёт -1. Сейчас проверяю. Это сообщение отредактировал(а) Cyr - 12.2.2015, 09:30 |
|||
|
||||
feodorv |
|
||||
Эксперт Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
С каким точно?))) Не минус ли 2? А какой errno?
Эх, а там есть ошибка, должно быть:
Это сообщение отредактировал(а) feodorv - 12.2.2015, 18:39 -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||
|
|||||
Cyr |
|
|||
Новичок Профиль Группа: Участник Сообщений: 48 Регистрация: 20.3.2006 Репутация: нет Всего: нет |
Ну вот. Спасибо.
Это сообщение отредактировал(а) Cyr - 13.2.2015, 10:47 |
|||
|
||||
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Сети | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |