Каково Различие Между чтением (), и recv (), и Между отправляют () и запись ()?

Между чем различие read() и recv(), и между send() и write() в программировании сокета с точки зрения действий, скорости и других поведений?

179
задан 7 revs, 4 users 80% 3 September 2019 в 15:54
поделиться

1 ответ

На Linux я также замечаю что:

Прерывание системных вызовов и библиотечных функций обработчиками сигналов
, Если обработчик сигналов вызывается, в то время как вызов системного вызова или библиотечной функции заблокирован, тогда также:

  • вызов автоматически перезапущен после возвратов обработчика сигналов; или

  • вызов приводит к сбою с ошибкой EINTR.

... Детали варьируются через системы UNIX; ниже, детали для Linux.

, Если заблокированный вызов к одному из следующих интерфейсов прерван обработчиком сигналов, то вызов автоматически перезапущен после возвратов обработчика сигналов, если флаг SA_RESTART использовался; иначе вызов приводит к сбою с ошибкой EINTR:

  • читает (2), readv (2), пишут (2), writev (2), и ioctl (2) запросы к "медленным" устройствам.

.....

следующие интерфейсы никогда не перезапускаются, будучи прерванным обработчиком сигналов, независимо от использования SA_RESTART; они всегда приводят к сбою с ошибкой EINTR при прерывании обработчиком сигналов:

  • "Входные" интерфейсы сокета, когда тайм-аут (SO_RCVTIMEO) был установлен на сокете с помощью setsockopt (2): примите (2), recv (2), recvfrom (2), recvmmsg (2) (также с непустым аргументом тайм-аута), и recvmsg (2).

  • "Выходные" интерфейсы сокета, когда тайм-аут (SO_RCVTIMEO) был установлен на сокете с помощью setsockopt (2): подключение (2), отправьте (2), sendto (2), и sendmsg (2).

Проверка man 7 signal для получения дополнительной информации.

<час>

А простое использование было бы сигналом использования избежать recvfrom блокирование неограниченно долго.

пример от APUE:

#include "apue.h"
#include <netdb.h>
#include <errno.h>
#include <sys/socket.h>

#define BUFLEN      128
#define TIMEOUT     20

void
sigalrm(int signo)
{
}

void
print_uptime(int sockfd, struct addrinfo *aip)
{
    int     n;
    char    buf[BUFLEN];

    buf[0] = 0;
    if (sendto(sockfd, buf, 1, 0, aip->ai_addr, aip->ai_addrlen) < 0)
        err_sys("sendto error");
    alarm(TIMEOUT);
    //here
    if ((n = recvfrom(sockfd, buf, BUFLEN, 0, NULL, NULL)) < 0) {
        if (errno != EINTR)
            alarm(0);
        err_sys("recv error");
    }
    alarm(0);
    write(STDOUT_FILENO, buf, n);
}

int
main(int argc, char *argv[])
{
    struct addrinfo     *ailist, *aip;
    struct addrinfo     hint;
    int                 sockfd, err;
    struct sigaction    sa;

    if (argc != 2)
        err_quit("usage: ruptime hostname");
    sa.sa_handler = sigalrm;
    sa.sa_flags = 0;
    sigemptyset(&sa.sa_mask);
    if (sigaction(SIGALRM, &sa, NULL) < 0)
        err_sys("sigaction error");
    memset(&hint, 0, sizeof(hint));
    hint.ai_socktype = SOCK_DGRAM;
    hint.ai_canonname = NULL;
    hint.ai_addr = NULL;
    hint.ai_next = NULL;
    if ((err = getaddrinfo(argv[1], "ruptime", &hint, &ailist)) != 0)
        err_quit("getaddrinfo error: %s", gai_strerror(err));

    for (aip = ailist; aip != NULL; aip = aip->ai_next) {
        if ((sockfd = socket(aip->ai_family, SOCK_DGRAM, 0)) < 0) {
            err = errno;
        } else {
            print_uptime(sockfd, aip);
            exit(0);
        }
    }

    fprintf(stderr, "can't contact %s: %s\n", argv[1], strerror(err));
    exit(1);
}
0
ответ дан 23 November 2019 в 20:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: