Я пытаюсь проверить закрытый сокет, который был изящно закрыт одноранговым узлом, не подвергая латентному удару двойной отправки, чтобы вызвать SIGPIPE
.
Одно из предположений здесь состоит в том, что сокет, если он был закрыт, был изящно закрыт одноранговым узлом сразу после его последней записи/отправки. Фактические ошибки, такие как преждевременное закрытие, рассматриваются иначе, чем в коде.
Если сокет все еще открыт, будет 0 или более байтов данных, которые я на самом деле не хочу выходить из буфера сокета еще.
Я думал, что могу позвонить int ret = recv(sockfd, buf, 1, MSG_DONTWAIT | MSG_PEEK);
, чтобы определить, все еще подключен сокет. Если он подключен, но нет данных в буфере, я получу возврат -1
с помощью errno == EAGAIN
и верните sockfd для повторного использования. Если он был изящно закрыт сверстником, я получу ret == 0
и открою новое соединение.
Я тестировал это, и он кажется работать. Тем не менее, я подозреваю, что есть небольшое окно между тем, когда я возвращаю последний бит моих данных и когда приходит peer FIN
, в котором я могу получить ложноположительный EAGAIN
из моего теста recv
.
Неужели это укусит меня, или есть лучший способ сделать это?