Проблема при попытке определить функцию сокета write_all () в C - PullRequest
0 голосов
/ 23 ноября 2011

В настоящее время я использую эту функцию в клиентской программе на Си.Кажется, все работает нормально, но когда сервер, к которому подключен этот клиент, выключен, write_all() возвращает 4 (это len) вместо ожидаемого -1.

int write_all(int sock, const void *buf, size_t len)
{
    int buf_size = len;
    while(len > 0)
    {
        int result = write(sock, buf, len);
        if(result < 0)
        {
            if(errno == EINTR)
                continue;
            return result;
        }
        buf += result;
        len -= result;
    }
    return buf_size;
}

Есть ли что-нибудьотсутствует в этой функции?Есть ли какая-либо другая функция, которую я могу вызвать заранее, чтобы убедиться, что сервер все еще работает?

Спасибо

Ответы [ 3 ]

1 голос
/ 23 ноября 2011

Вы говорите «выключить», вы имеете в виду, что вы выключаете питание без корректного закрытия TCP?

В этом случае вызов write возвращается с успехом.Данные находятся в буфере отправки TCP, а стек TCP еще не знает, что узел отключен.Программа получит EPIPE или другую ошибку во время последующих вызовов.

Стек TCP будет пытаться выполнить повторную передачу некоторое время, прежде чем принять решение об ошибке подключения.

0 голосов
/ 24 ноября 2011

Примечание: Я предполагаю, что здесь TCP.

Из возвращаемого значения я понимаю, что клиент сумел записать 4 байта в буфер отправки, прежде чем узнает, что сервер закрыл его.конец или иным образом исчез.Если он исчез без надлежащего закрытия, единственный способ узнать это - тайм-аут отправки.Следующие write, shutdown или close после этого получат ошибку.

Если вы хотите получать быстрое уведомление об исчезновении конечных точек без необходимости постоянно отправлять данные, вы можете активировать опцию keepalive сокета,В Linux это были бы setsockopt(..., SOL_SOCKET, SO_KEEPALIVE, ...) и TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_KEEPCNT на уровне SOL_TCP.

0 голосов
/ 23 ноября 2011

Для меня это выглядит так, будто вам не удастся реализовать какое-то рукопожатие.

Как будто вашему отправителю недостаточно знать, что отправленные им данные были полностью получены (я полагаю,случай), но он также должен знать, если получатель выполнил какие-либо обработки, вы ожидаете от механики сокета большего, чем они могут предоставить ...

Сокеты - это просто передатчик.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...