Эту проблему я наблюдал и на С++ и на С# и на java ...
Причем успешно прочитать 0 байт можно как минимум по 2 причинам
1) Есть сокетные соединения с программой Android OC при бездействии экрана на противоположенном конце может прийти несколько пустых пакетов (может баг???)
2) Если одну из программ придушить диспетчером задач, то на противоположенном конце часто периодически сыплются такие пустые приёмы и грузят процессор довольно долго(покудо вдруг Win не сообразит выдать ошибку)
Как в таких случаях быть?
Что можно придумать кроме отсылки NOOP с таймаутом?
Здравствуйте, vsb, Вы писали:
vsb>man read
vsb>On success, the number of bytes read is returned (zero indicates end of file)
vsb>В случае сокета это означает, что соединение закрыто. Непонятно, в чём тут проблема? Прочитал 0, закрыл соединение со своей стороны и всё.
кстати ты прав но почему для закрытых сокетов есть отдельные коды ошибок?
Здравствуйте, vvv848165@ya.ru, Вы писали:
VYR>кстати ты прав но почему для закрытых сокетов есть отдельные коды ошибок?
Про какие именно коды ошибок идёт речь? Возможно ты говоришь о ситуации, когда сокет закрыт ненормальным образом, например connection reset.
Т.е. соединение может быть закрыто нормальным образом, когда та сторона вызывает shutdown, в этом случае приходят одни пакеты (FIN).
Соединение может быть "оборвано", например если на той стороне программа упала и соединение подчищает уже ОС или программа вызвала close без shutdown. В этом случае приходят другие пакеты (RST).
А ещё соединение может просто отвалиться по таймауту, если давно не приходило никаких пакетов с той стороны. Это тоже ошибка.
В общем лучше всего подцепиться wireshark-ом и смотреть на конкретные пакеты и то, как они соотносятся с вызываемыми функциями/возвращаемыми значениями.
Ты прав! но как определить конкретный случай ? чтобы не закрыть случайно не совсем безнадёжное соединение из-за одного нулевого ?
vsb>А ещё соединение может просто отвалиться по таймауту, если давно не приходило никаких пакетов с той стороны.
вроде почти день тестил соединения Win — Win или и Android — Android по таймауту так просто не обрывались
а вот Win — Android или любой *nix — Android жди кучу бед (одно из них пустые пакеты)
Здравствуйте, vvv848165@ya.ru, Вы писали:
VYR>Эту проблему я наблюдал и на С++ и на С# и на java ... VYR>Причем успешно прочитать 0 байт можно как минимум по 2 причинам
Для TCP прочтение 0 байт — надежный признак того, что соединение закрыли с другой стороны. В случае UDP реально можно получить пустой пакет (пакет, содержащий 0 байтов данных). Но зато у UDP не бывает закрытия соединения с другой стороны.
Здравствуйте, netch80, Вы писали:
N>На TCP это означает, что та сторона закрылась — можно дальше читать до посинения, будет только ответ 0. N>На UDP — пустая датаграмма (законная штука).
Здравствуйте, Pzz, Вы писали:
Pzz>Здравствуйте, netch80, Вы писали:
N>>На TCP это означает, что та сторона закрылась — можно дальше читать до посинения, будет только ответ 0. N>>На UDP — пустая датаграмма (законная штука).
Pzz>А для SCTP?
Отправка пустого сообщения получает отказ EINVAL — по крайней мере под Linux и BSD.
Поэтому чтение аналогично TCP — пришла длина 0, значит, закрыли с той стороны.
Здравствуйте, Pzz, Вы писали:
Pzz>Ну например потому, что кроме нормального закрытия соединения бывают еще всякие аварийные варианты. И их может возникнуть желание отличать.
а как-нибудь что-нибудь дополнительно можно узнать при получении 0 байт по TCP-IP (ну хоть через какие нибудь Api)?
Здравствуйте, vvv848165@ya.ru, Вы писали:
M>>Не понятно, какой конкретный случай ты собрался определять?
VYR>Дак уже говорили что 0 байт может прийти например из-за Shutdown в одну сторону...
Ну и закрывай себе. Либо отправляй то что хотел напоследок, и опять же закрывай. В чём проблема-то?
Здравствуйте, vvv848165@ya.ru, Вы писали:
VYR>Эту проблему я наблюдал и на С++ и на С# и на java ...
Может вы всё-таки будете внимательно читать документацию по сокетам? Там явно сказано всё то, что вам в теме написали. Прямо вот на MSDN, и ещё в паре десятков книжек и примеров по сетевому программированию.
Здравствуйте, vvv848165@ya.ru, Вы писали:
Pzz>>Ну например потому, что кроме нормального закрытия соединения бывают еще всякие аварийные варианты. И их может возникнуть желание отличать.
VYR>а как-нибудь что-нибудь дополнительно можно узнать при получении 0 байт по TCP-IP (ну хоть через какие нибудь Api)?
В таких аварийных вариантах вы получите не 0, а -1, и уточняющий код в errno.
Здравствуйте, vvv848165@ya.ru, Вы писали:
vsb>> это означает, что соединение закрыто
VYR>Вот то-то и оно что для этого есть специальные коды ошибок и исключения, а не успешный 0 !
Таки непонятен ваш плач. Я правильно понял, что речь, что на той стороне программа не сама решила завершить передачу по соединению в соответствии со своей штатной логикой, а её вместо этого пришлёпнули, и вам хотелось бы видеть в этом случае другой код, чем 0?
Если да — я согласен, что тут есть проблема. Она есть и в варианте локального пайпа (шелл собрал цепочку типа xx | yy, xx отстрелили — yy получит только EOF), и в сетевом. Увы. Но так как сетевое соединение двустороннее, можно спросить состояние — а можно добавить явную метку конца в протокол. Или как на HTTP сделано: посылайте Content-Length или используйте chunked TE, тогда метка завершения всегда будет явной.
Я бы при проектировании этого интерфейса подумал про такие индикации. Но раз за ~30 лет их активного использования не исправляли — проблема считается не настолько серьёзной.
Здравствуйте, netch80, Вы писали:
N>Таки непонятен ваш плач. Я правильно понял, что речь, что на той стороне программа не сама решила завершить передачу по соединению в соответствии со своей штатной логикой, а её вместо этого пришлёпнули, и вам хотелось бы видеть в этом случае другой код, чем 0?
Разве в таком случае будет 0? Вроде должен прийти пакет RST и будет -1 с econnreset.
Здравствуйте, vsb, Вы писали:
N>>Таки непонятен ваш плач. Я правильно понял, что речь, что на той стороне программа не сама решила завершить передачу по соединению в соответствии со своей штатной логикой, а её вместо этого пришлёпнули, и вам хотелось бы видеть в этом случае другой код, чем 0?
vsb>Разве в таком случае будет 0? Вроде должен прийти пакет RST и будет -1 с econnreset.
Проверьте у себя, не вопрос.
Я вижу, что Linux и FreeBSD — возвращают 0.