Запись по закрытому соединению не генерирует sigpipe сразу

У меня эта проблема с моим сервером / клиентом на C. Если я закрываю сокет сервера после SIGINT, и затем я пытаюсь записать это закрытое соединение от клиента, мне нужно сделать запись два раза, прежде чем клиент сгенерирует SIGPIPE, Разве это не должно генерировать это немедленно? Это нормальное поведение или что-то, что мне нужно исправить? Это мой код Я тестирую вещи на Ubuntu, на том же ПК, подключаясь через 127.0.0.1.

server.c

sigset_t set;
struct sigaction sign;
int sock_acc;
int sock;

void closeSig(){
    close(sock_acc);
    close(sock);
    exit(1);
}


int main(){
    sigemptyset(&set);
    sigaddset(&set, SIGINT);
    sig.sa_sigaction = &closeSig;
    sig.sa_flags = SA_SIGINFO;
    sig.sa_mask = set;
    sigaction(SIGINT, &sig, NULL);
    //other code to accept the connection from the client
    sigprocmask(SIG_UNBLOCK, &set, NULL);
    //write/read calls
}

client.c

void closeSigPipe(){
    close(ds_sock);
    printf("Stop...");
    exit(1);
}

int main(){
    sigpipe.sa_sigaction = &closeSigPipe;
    sigpipe.sa_flags = SA_SIGINFO;
    sigaction(SIGPIPE, &sigpipe, NULL);
    //other code to connect the server, and write/read calls
}

Проблема в том, что когда я закрываю серверный терминал с помощью CTRL+C, первая запись в соединение с клиента работает без каких-либо проблем... perror("Error:"); печатает "успех"...

1 ответ

Решение

Протокол TCP не позволяет получателю сообщить отправителю, что он закрывает соединение. Когда он закрывает соединение, он отправляет FIN сегмент, но это просто означает, что он завершил отправку, а не то, что он больше не может получать.

Отправитель обнаруживает, что соединение было закрыто, и пытается отправить данные, а получатель отправляет обратно RST сегмент в ответ. Но запись в сокет не ждет ответа, он просто ставит в очередь данные и немедленно возвращает. Сигнал возникает, когда RST получено, что будет через некоторое время.

Причина, по которой вы должны сделать две записи, может быть из-за алгоритма Nagle. Чтобы избежать чрезмерной нагрузки на сеть, TCP пытается объединить короткие сообщения в один сегмент. На странице Википедии есть некоторые обходные пути для этого.

Другие вопросы по тегам