Идёт активный опрос (вопрос-ответ) удалённой системы. Периодически не приходят целые цепочки (Прогресс роста ~ 1, 5, 50, 100, ...) ответов, хотя снифер видит соответствующие пакеты. Чем дольше программа работает, тем больше эти "провалы". За семь минут 200 пакетов.
Я чего то не пойму, Вы TCP используете? Или присоединенный UDP сокет? В первом случае ни о каких пакетах речь не может идти — транспортный драйвер собирает поток как ему заблагорассудится — может по байту отдавать, а может и по 10 кб — величина в общем случае не связана с размером пакета, переданного через сеть ( хотя естественно корреляция наблюдается обычно ). Если это UDP сокет — то при активном обмене может просто переполняться буфер драйвера, он не будет для вас там тыщщи пакетов хранить.
Вообще то ТСР (в имени функции присутствует).
Режим вопрос-ответ. Пакеты просто не могут переполнять буфер, поскольку приходят по одному.
Снифер их все видит.
И не понятно откуда берётся закономерность:
256-й
513, 515
771, 773, 775
1030, 1032, 1034, 1036
и т.д.
Если Вы работаете с TCP, то не стоит искать соответствия между получаемыми данными через ф. recv и принятыми пакетами. Т.е вы видите сниффером, что пришло 10 пакетов по протоколу TCP. Если Вы при этом в цикле вызываете recv — она может сработать от 0 до 10 раз ( а может и больше — зависит от размера буфера ). Если у Вас теряются данные — ищите ошибку в коде.
Ux>И не понятно откуда берётся закономерность: Ux>256-й Ux>513, 515 Ux>771, 773, 775 Ux>1030, 1032, 1034, 1036 Ux>и т.д.
А закономерностей искать не надо — этак можно до дурки дойти.
Здравствуйте, TarasCo, Вы писали:
TC>Если Вы работаете с TCP, то не стоит искать соответствия между получаемыми данными через ф. recv и принятыми пакетами.
Прийти должен только один пакет. И он приходит, но из сокета вычитать я его не могу. И не получаю каждый 256-й с ростом непринятых на один с чередованием через один.
TC>А закономерностей искать не надо — этак можно до дурки дойти.
Если бы она не повторялась на других компах. И в других компиляторах. В Висуал 6.0 та же фигня.
Здравствуйте, Ux, Вы писали:
Ux>Прийти должен только один пакет. И он приходит, но из сокета вычитать я его не могу.
Всё ты можешь, только зачем-то наворотил селектов с таймаутами (кстати, и даже после "неудачного" селекта ты всё равно можешь спокойно прочитать данные).
Ux>И не получаю каждый 256-й с ростом непринятых на один с чередованием через один.
Тебе уже объяснили два раза, почему это происходит.
Ux>Если бы она не повторялась на других компах. И в других компиляторах. В Висуал 6.0 та же фигня.
Причем тут компиляторы? Скажу тебе страшную тайну — точно такую же картину ты бы увидел и на Delphi и на C# и на Java
Здравствуйте, Michael Chelnokov, Вы писали:
MC>Всё ты можешь, только зачем-то наворотил селектов с таймаутами (кстати, и даже после "неудачного" селекта ты всё равно можешь спокойно прочитать данные).
Иначе просто клинит программу на этом самом 256-м чтении. Прочитать данные соответственно не могу.
MC>Тебе уже объяснили два раза, почему это происходит.
Не объяснили.
Я всегда получаю целые пакеты.
75 байт данных, хотя буфер для ресива несколько больше.
Следующее обращение получает удачный ответ.
А через одно опять ошибка.
При этом более одного пакета данных за раз я не получаю.
Клиентская часть проверялась на двух компьютерах. Драйвера сетевых карт соответственно разные.
Возжность присутствия ошибки я признаю, но её найти не могу.
MC>Причем тут компиляторы? Скажу тебе страшную тайну — точно такую же картину ты бы увидел и на Delphi и на C# и на Java
Я не был бы столь категоричен.
П.С. Я просто хотел "услышать" мнение человека, который с таким сталкивался.
Здравствуйте, Ux, Вы писали:
MC>>Ладно, начнем сначала. Зачем тебе там вообще потребовался select с таймаутом? Ux>Для проверки наличия данных для чтения в сокете.
Зачем это тебе нужно? recv все равно вернет данные.
Ux>А что что-то не так?
Да все так, только ты почему-то удивляешься получению результата, ради которого и наворачивал весь этот код с select и таймаутом. Если бы твоя функция была из одной строчки (вызова recv), то у тебя бы не возникло вопросов.
MC>Зачем это тебе нужно? recv все равно вернет данные.
Не вернёт, если не было дисконекта, сокет блокируемый и пакет не пришёл. И будет тупо ждать данных.
Сделал одним ресивом с включеной опцией таймаута. Та же прогрессия пропадания пакетов.
Здравствуйте, Ux, Вы писали:
MC>>Зачем это тебе нужно? recv все равно вернет данные. Ux>Не вернёт, если не было дисконекта, сокет блокируемый и пакет не пришёл. И будет тупо ждать данных.
Пусть ждет. Нет данных — ждет, появятся — вернет. Пропадет передатчик — recv отвалится по таймауту сам, расценивай это как disconnect.
MC>Пусть ждет. Нет данных — ждет, появятся — вернет. Пропадет передатчик — recv отвалится по таймауту сам, расценивай это как disconnect.
1. А я думал, что дисконнект проверяется по возврату нуля от этой функции.
2. Мне что писать отдельный поток для приёма данных из сокета? А потом их синхронизировать?
3. Почему ни кого не удивляет наличие подобной прогрессии по пропаданию пакетов? На 256-м пакете прогу обязательно заклинит, а это 21-я секунда работы системы. Не помогает даже дисконнект и открытие новой сессии.
Здравствуйте, Ux, Вы писали:
MC>>Пусть ждет. Нет данных — ждет, появятся — вернет. Пропадет передатчик — recv отвалится по таймауту сам, расценивай это как disconnect.
Ux>1. А я думал, что дисконнект проверяется по возврату нуля от этой функции.
0 — другая сторона говорит что больше данных не будет. По соединению все еще можно передавать данные с твоей стороны.
-1 — ошибка, под виндой смело можешь считать что соединение сдохло.
Ux>2. Мне что писать отдельный поток для приёма данных из сокета? А потом их синхронизировать?
Нафига?
Ux>3. Почему ни кого не удивляет наличие подобной прогрессии по пропаданию пакетов?
Я уже устал повторять что никакого пропадания не происходит, дело в твоем коде с select и таймаутом.
А никого это не удивляет, поскольку так работает TCP. Для повышения скорости передачи данных TCP пытается обьединить как можно больше порций данных в один сегмент. Описание можешь почитать здесь. Отключается на стороне передатчика установкой опции TCP_NODELAY.
MC>0 — другая сторона говорит что больше данных не будет. По соединению все еще можно передавать данные с твоей стороны. MC>-1 — ошибка, под виндой смело можешь считать что соединение сдохло.
If no error occurs, recv returns the number of bytes received. If the connection has been gracefully closed, the return value is zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.
MC>А никого это не удивляет, поскольку так работает TCP. Для повышения скорости передачи данных TCP пытается обьединить как можно больше порций данных в один сегмент.
Ну не объединяет он. В дампе снифера нормальные Езернет фреймы с одиночными пакетами. Всё в порядке вопрос-ответ.
Здравствуйте, Ux, Вы писали:
MC>>0 — другая сторона говорит что больше данных не будет. По соединению все еще можно передавать данные с твоей стороны. MC>>-1 — ошибка, под виндой смело можешь считать что соединение сдохло.
Ux>If no error occurs, recv returns the number of bytes received. If the connection has been gracefully closed, the return value is zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.
И где отличия от того что я написал?
Слушай, я уже 10 лет этим кормлюсь. Неужели ты думаешь что данный текст мне неизвестен? Да я его наизусть знаю, как букварь.
MC>>А никого это не удивляет, поскольку так работает TCP. Для повышения скорости передачи данных TCP пытается обьединить как можно больше порций данных в один сегмент.
Ux>Ну не объединяет он. В дампе снифера нормальные Езернет фреймы с одиночными пакетами. Всё в порядке вопрос-ответ.