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

Я столкнулся с той же проблемой. Решил это, перейдя на левую боковую панель в Metro Bundler и отправив ссылку по электронной почте!

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

5 ответов

Разница в том, что recv () / send () работают только с дескрипторами сокетов и позволяют указать определенные параметры для фактической операции. Эти функции немного более специализированы (например, вы можете установить флаг для игнорирования SIGPIPE или для отправки внеполосных сообщений ...).

Функции read () / write () - это универсальные функции файловых дескрипторов, работающие со всеми дескрипторами.

118
ответ дан 23 November 2019 в 20:13
поделиться

На 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
поделиться

«Производительность и скорость»? Разве здесь не такие ... синонимы?

В любом случае, вызов recv () принимает флаги, которых не поддерживает read () , что делает его более мощным. , или хотя бы удобнее. Это одно отличие. Я не думаю, что есть существенная разница в производительности, но не тестировал на это.

3
ответ дан 23 November 2019 в 20:13
поделиться

Согласно первое попадание в Google

read () эквивалентно recv () с параметром flags 0. Другие значения параметра flags изменяют поведение recv ( ). Аналогично write () эквивалентен send () с флагами == 0.

82
ответ дан 23 November 2019 в 20:13
поделиться

read() и write() более общие, они работают с любым дескриптором файла. Однако они не будут работать на Windows.

Вы можете передать дополнительные опции в send() и recv(), так что в некоторых случаях вам может понадобиться их использовать.

11
ответ дан 23 November 2019 в 20:13
поделиться
Другие вопросы по тегам:

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