Programing

읽기()와 recv()의 차이점과 보내기()와 쓰기()의 차이점은 무엇인가?

c10106 2022. 5. 4. 21:21
반응형

읽기()와 recv()의 차이점과 보내기()와 쓰기()의 차이점은 무엇인가?

와의 차이점은 무엇인가?read()그리고recv(), 그리고 사이send()그리고write()성능, 속도 및 기타 동작의 측면에서 소켓 프로그래밍에 있어?

차이점은 이다.recv()/send()소켓 설명자에서만 작동하며 실제 작업에 대한 특정 옵션을 지정할 수 있다.이러한 기능은 약간 더 전문화되어 있다(예를 들어, 플래그를 무시하도록 설정할 수 있음).SIGPIPE또는 대역 외 메시지를 보내려면...)

기능들read()/write()범용 파일 설명자 함수가 모든 설명자에서 작동하는지 여부.

구글의 첫 번째 히트곡에 따라

readvates는 플래그 파라미터가 0인 recvating과 같다.플래그 매개변수에 대한 다른 값은 recv()의 동작을 변경한다.마찬가지로 쓰기()는 플래그 == 0으로 보내는 것과 같다.

Linux에서 나는 또한 다음을 주목한다.

신호 처리기에 의한 시스템 호출 및 라이브러리 기능 중단
시스템 호출 또는 라이브러리 함수 호출이 차단된 상태에서 신호 처리기가 호출되는 경우 다음 중 하나를 수행하십시오.

  • 신호 처리기가 돌아온 후 통화가 자동으로 다시 시작됨; 또는

  • EINTR 오류로 인해 호출이 실패함.

...상세한 내용은 UNIX 시스템마다 다르며, 이하 리눅스에 대한 상세 내역이다.

다음 인터페이스 중 하나에 대한 차단된 통화가 신호 핸들러에 의해 중단되는 경우, 신호 핸들러가 SA_RESTART 플래그를 사용한 경우 복귀한 후 통화가 자동으로 다시 시작되며, 그렇지 않은 경우 통화가 실패하고 EINTR:

  • "느린" 장치에 대한 read(2), readv(2), write(2), writev(2), ioctl(2) 호출.

.....

다음 인터페이스는 SA_RESTART의 사용과 관계없이 신호 핸들러에 의해 중단된 후 다시 시작되지 않는다. 신호 핸들러에 의해 중단될 경우 항상 오류 EINTR과 함께 실패한다.

  • "입력" 소켓 인터페이스는 setsockopt(2)를 사용하여 소켓에 시간 초과(SO_RCVTIMO)가 설정된 경우: accept(2), recvv(2), recvmmsg(2), recvmmsg(2)(NULL이 아닌 시간 초과 인수 포함) 및 recvmsg(2)를 사용한다.

  • "출력" 소켓 인터페이스: setsockopt(2)를 사용하여 소켓에 시간 초과(SO_RCVTIMO)가 설정된 경우: connect(2), send(2), sendto(2), sendmg(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);
}

read()그리고write()좀 더 일반적이어서, 어떤 파일 설명자와도 작동한다.하지만 그들은 윈도우에서는 작동하지 않을 것이다.

추가 옵션을 다음으로 전달할 수 있다.send()그리고recv()그래서 당신은 어떤 경우에는 그것들을 사용해야 할지도 모른다.

내가 최근에 알아낸건 내가 사용했을때write()Windows의 소켓에서, 그것은 거의 작동한다. (FD는 에 전달되었다.)write()에게 전해진 것과 같지 않다.send(); 나는 사용_open_osfhandle()를 FD를 에게 write()그러나 문자 10이 포함된 이진 데이터를 보내려 해도 효과가 없었다.write()어디선가 13자를 삽입했어변경send()플래그 매개변수 0으로 그 문제를 해결했다.read()13-10이 2진수 데이터에서 연속되는 경우 역 문제가 발생할 수 있지만, 나는 테스트하지 않았다.그러나 그것은 또 다른 가능한 차이점인 것 같다.send()그리고write().

"성능과 속도"?그런... 동의어들이 여기 있지?

아무튼 더.recv()호출은 라는 깃발을 내디딘다read()그렇지 않아, 그래서 더 강력하거나 적어도 더 편리해지지그것은 하나의 차이점이다.나는 성능 차이가 크지 않다고 생각하지만, 아직 테스트하지 않았다.

리눅스의 또 다른 점은 다음과 같다.

send비응축 fd에서는 작동이 허용되지 않는다.따라서 예를 들어 usb 포트에 쓰기 위해write꼭 필요하다.

참조URL: https://stackoverflow.com/questions/1790750/what-is-the-difference-between-read-and-recv-and-between-send-and-write

반응형