recv

Autres langues

Langue: ko

Version: 1999년 4월 (fedora - 25/11/07)

Section: 2 (Appels système)

이름

recv, recvfrom, recvmsg - 소켓으로부터 메세지를 받는다.

사용법

#include <sys/types.h>
#include <sys/socket.h>

int recv(int s, void *buf, size_t len, int flags);

int recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);

int recvmsg(int s, struct msghdr *msg, int flags);

설명

recvfrom 그리고 recvmsg 는 연결 지향형이든지 아니든지 소켓에서 메세지를 받기 위해 사용된다. 그리고 소켓에 있는 데이터를 받기 위해 사용된다.

만일 from 가 NULL이 아니고 소켓이 연결 지향형이 아니라면, 메세지의 원 주소가 채워진다. 인자 fromlen 는 값-결과 변수이며 from과 관련된 버퍼의 크기로 초기화되며 반환시 저장되는 주소의 실제 크기를 가리키는 값으로 수정된다.

recv 호출은 보통 connected 된 소켓에서만 사용된다. ( connect(2)를 참조해라) 그리고 from 인자를 가진 recvfrom 와 동일하다.

세 루틴 모두 성공적인 완성시 메세지의 길이를 반환한다. 만일 메세지가 제공되는 버퍼보다 더 크다면, 초과된 바이트들은 메세지를 받은 소켓 타입에 의존하여 버려진다.( socket(2)를 참조해라).

만일 어떤 메세지들도 소켓에서 이용할수 없다면, 받는 소켓 호출 함수들은 만일 -1을 반환하고 외부 변수 errnoEAGAIN으로 설정하는 경우의 nonblocking이 아니라면 메세지가 도착할때까지 기다린다.( fcntl(2)를 참조해라.) 메세지를 받는 함수들은 보통 요구된 완전한 양을 기다리기 보다는 요구된 양까지 이용할수 있는 데이타를 반환한다.

select(2) 나 poll(2) 호출은 데이터가 더 도착하였는지를 결정하기 위해 사용된다.

받는 함수들을 위한 flags 인자는 다음 값들 중 하나이상의 OR로 구성된다.:

MSG_OOB
이 플래그는 일반적 데이터 스트림에서 받지 않는 out-of-band 데이터를 요구한다. 몇몇 프로토콜은 보통 데이터 큐의 머리에 급한 데이터를 놓는다. 그리고 이 플래그는 그런 프로토콜에서는 사용될수 없다.
MSG_PEEK
이 플래그는 큐에서 데이터를 제거하는것 없이 받는 큐의 시작에서 데이터를 반환하기 위한 받기 작동을 야기한다. 그리고, 연속적인 받기 호출은 같은 데이터를 반환한다.
MSG_WAITALL
이 플래그는 완전한 요구가 만족될때까지 작동을 블럭킹하도록 요구한다. 그러나, 만일 신호가 발생하고, 에러나 단절이 발생하거나 받은 다음 데이터가 전에 반환된 데이터와 다른 타입이라면 호출은 여전히 반환된다.
MSG_NOSIGNAL
이 플래그는 다른 종점이 사라졌을때 스트림 소켓에서 SIGPIPE 가 발생하는것을 막는다(끈다).
MSG_ERRQUEUE
이 플래그는 소켓 에러 큐에서 받아야하는 에러들을 큐하도록 지정한다. 에러는 프로토콜(IPv4를 위한 IP_RECVERR ) 에 의존하여 타입과 보조테이터와 함께 전달된다. 사용자는 충분한 크기의 버퍼를 제공해야 한다.

보조 메세지들에서 더 많은 정보를 원하면 cmsg(3)를 참조해라

에러는 sock_extended_err 구조체로 제공된다:

 
 #define SO_EE_ORIGIN_NONE       0
 #define SO_EE_ORIGIN_LOCAL      1
 #define SO_EE_ORIGIN_ICMP       2
 #define SO_EE_ORIGIN_ICMP6      3
 
 struct sock_extended_err
 {
     u_int32_t       ee_errno;   /* error number */
     u_int8_t        ee_origin;  /* where the error originated */ 
     u_int8_t        ee_type;    /* type */
     u_int8_t        ee_code;    /* code */
     u_int8_t        ee_pad;
     u_int32_t       ee_info;    /* additional information */
     u_int32_t       ee_data;    /* other data */  
     /* More data may follow */ 
 };
 
 struct sockaddr *SOCK_EE_OFFENDER(struct sock_extended_err *);
 
 
ee_errno 는 큐된 에러의 에러 번호를 포함한다. ee_origin 는 에러가 시작됐던 원 코드이다. 다른 필드들은 프로토콜에 의존한다. 매크로 SOCK_EE_OFFENDER 는 보조 메세지에 대한 주어진 포인터에서 에러가 발생한 네트웍 객체의 주소에 대한 포인터를 반환한다.
만일 이 주소가 알려지지 않았다면, sockaddr 의 멤버인 sa_familyAF_UNSPEC 를 포함하며 sockaddr 의 다른 필드들은 정의되지 않는다. 에러를 야기한 패킷은 보통 데이터처럼 전달된다.
로컬 에러들을 위해, 어떤 주소도 전달되지 않는다.( 이것은 cmsghdr의 cmsg_len 멤버와 함께 체크된다.) 에러를 받기 위해, MSG_ERRQUEUEmsghdr에 설정된다.
에러가 전달된후, 미결인채로 남아 있던 소켓 에러들은 다음 큐된 에러에 기반하여 다시 만들어지고 다음 소켓 작동시 전달된다.

recvmsg 는 제공된 파라미터들의 수를 최소화하기 위해 msghdr 구조체를 사용한다. 이 구조체는 <sys/socket.h>에 정의된 것처럼 다음 형태를 가지고 있다.:

 
 struct msghdr {
     void         * msg_name;     /* optional address */
     socklen_t    msg_namelen;    /* size of address */
     struct iovec * msg_iov;      /* scatter/gather array */
     size_t       msg_iovlen;     /* # elements in msg_iov */
     void         * msg_control;  /* ancillary data, see below */
     socklen_t    msg_controllen; /* ancillary data buffer len */
     int          msg_flags;      /* flags on received message */
 };
 
 

msg_namemsg_namelen 는 만일 소켓이 연결되지 않았다면 목적지 주소이다. msg_name 는 만일 어떤 이름도 원하지 않거나 필요하지 않다면 null 포인터로써 주어진다. msg_iovmsg_iovlen 필드는 readv(2)처럼 scatter-gather 위치를 가리킨다.

The field which has length msg_controllen의 길이를 가지고 있는 msg_control는 메세지나 기타 보조 데이터와 관련된 다른 프로토콜 제러를 위한 버퍼를 가리킨다. recvmsg 가 호출될때, is called, 는 msg_control에서 이용할수 있는 버퍼의 길이를 포함해야 한다.; 연속적인 호출에서 반환시 제어 메세지의 순서의 길이를 포함해야 한다.

메세지의 형태는:

 
 struct cmsghdr {
     socklen_t   cmsg_len;   /* data byte count, including hdr */
     int         cmsg_level; /* originating protocol */
     int         cmsg_type;  /* protocol-specific type */
 /* followed by
     u_char      cmsg_data[]; */
 };
 
 

보조 데이터는 cmsg(3)에서 정의된 매크로에 의해서만 접근되어야 한다.

예를 들어, 리눅스는 이 보조 데이터를 IP 옵션이나 Unix 소켓에서 파일기술자들처럼 확장된 에러들을 전달하기 위해 사용한다.

msg_flags 필드는 받은 메세지에 따라 리턴시 설정된다. MSG_EOR 는 end-of-record를 가리킨다; 반환된 데이터가 기록을 마쳤다.(일반적으로 SOCK_SEQPACKET타입의 소켓시 사용된다). MSG_TRUNC 는 데이터 그램의 끝 부분을 버렸다는 것을 가리킨다. 왜냐하면 데이터 그램이 제공되는 버퍼보다 크기 때문이다.

MSG_CTRUNC 는 몇몇 제어 데이터들을 보조 데이터를 위한 버퍼 공간이 부족하기때문에 버렸다는 것을 가리킨다. MSG_OOB 는 급하거나 out-of-band 데이터를 받았다는것을 가리키기 위해 반환된다. MSG_ERRQUEUE 는 어떤 데이터도 받지 않았지만 소켓 에러 큐에서 에러가 확장되었다는 것을 가리 킨다.

반환값

이들 호출은 받은 바이트들의 수를 반환한다. 에러가 발생하면 -1을 반환한다.

에러

이것들은 소켓 층에서 발생하는 몇몇 표준 에러이다. 추가적인 에러들은 프로토콜 모듈들 아래에서 발생되고 반환된다; 해당 메뉴얼 페이지들을 참조해라.
EBADF
인자 s 가 유효한 기술자가 아니다.
ENOTCONN
소켓은 연결 지향형 프로토콜이지만 연결되지 않았다.( connect(2)와 accept(2)를 참조해라).
ENOTSOCK
인자 s 가 소켓을 가리키지 않는다.
EAGAIN
소켓이 non-blocking이고 받는 작동은 블럭킹되어 있거나 받는 타임아웃이 설정되어 있고 데이터를 받기 전에 타임아웃이 끝났다.
EINTR
받기가 데이터를 이용하기 전에 전달된 신호에 의해 인터럽트 되었다.
EFAULT
받는 버퍼 pointer(s)가 프로세스 주소 공간이외를 가리키고 있다.
EINVAL
무효한 인자가 전달되었다.

호환

4.4BSD (이 함수는 4.2BSD에서 처음 나타났다.)

주의

위에 주어진 원형은 glibc 이후이다. Single Unix Specification은 `ssize_t' 타입의 반환값을 가지는 것외에 같다. (반면에 BSD 4.* 그리고 libc4, libc5는 모두 `int'이다.). flags 인자는 BSD 4.* 에서 `int'이지만, libc4와 libc5는 `unsigned int' 이다. len 인자는 BSD 4.*에서 `int'이지만, libc4와 libc5는 'size_t'이다. fromlen 인자는 BSD 4.*, libc4, libc5에서 `int *'이다. 현재 `socklen_t *'는 POSIX에 의해 만들어졌다. accept(2)를 참조해라.

관련 항목

fcntl(2), read(2), select(2), getsockopt(2), socket(2), cmsg(3)

역자

정강훈 <skyeyes@soback.kornet.net>, 2000년 12월 11일