Какова лучшая практика, чтобы предотвратить аварию здесь?
Либо отключите sigpipes для всех, либо поймайте и проигнорируйте ошибку.
Есть ли способ проверить, читает ли другая сторона строки?
Да, используйте select ().
select () здесь не работает, так как всегда говорит, что сокет доступен для записи.
Вы должны выбрать биты для чтения . Вы, вероятно, можете игнорировать биты записи .
Когда дальний конец закроет свой дескриптор файла, select скажет вам, что есть данные, готовые для чтения. Когда вы пойдете и прочитаете это, вы получите обратно 0 байтов, и именно так ОС сообщает вам, что дескриптор файла был закрыт.
Единственный раз, когда вы не можете игнорировать биты записи, это если вы отправляете большие тома, и существует риск того, что другой конец будет засорен, что может привести к заполнению ваших буферов. Если это произойдет, то попытка записи в дескриптор файла может привести к блокировке или неудаче вашей программы / потока. Тестирование select перед записью защитит вас от этого, но это не гарантирует, что другой конец исправен или что ваши данные будут доставлены.
Обратите внимание, что вы можете получить sigpipe из close (), а также когда вы пишете.
Закрыть сбрасывает любые буферизованные данные. Если другой конец уже был закрыт, то закрыть не удастся, и вы получите сигпайп.
Если вы используете буферизованный TCPIP, то успешная запись означает, что ваши данные были поставлены в очередь для отправки, но это не значит, что они были отправлены. Пока вы успешно не позвоните близко, вы не знаете, что ваши данные были отправлены.
Сигпайп говорит вам, что что-то пошло не так, он не говорит вам, что или что вы должны с этим делать.