RECV(2) 리눅스 프로그래머 매뉴얼 RECV(2)
이름
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 호출은 보통 연결된소켓에서만 사용된다. ( connect(2)를참조하라) 그리고 from 인자를 가진 recvfrom과동일하
다.
소켓에 메시지가 없다면, 메시지를 받는 호출은 메시지가 들어올때까지 기다리게되며, 만약 소켓이 넌블럭킹( fcntl(2)
참 조)이었다면 결과값은 -1이 되고 errno를 EAGAIN으로설정한다. 일반적으로 메시지를 받는 호출들은 요구된 양을 모
두 채우며 기다리기 보다는 채워진 양을 리턴한다.
select(2) 나 poll(2) 호출은 데이터가 더 도착하였는지를 결정하기 위해 사용된다.
받는 함수들을 위한 flags 인자는 다음 값들 중 하나 이상의 OR로구성된다.:
MSG_OOB
이 플래그는 일반적 데이터 스트림에서 받지 않는 out-of-band 데이터를 요구한다. 몇몇 프로토콜은 보통 데이
터 큐의 머리에 급한 데이터를 놓는다. 그리고 이플래그는 그런 프로토콜에서는 사용될 수 없다.
MSG_PEEK
이 플래그는 큐에서 데이터를 제거하지 않고 받는 큐의 시작에서부터 데이터를반환하는 받기 작동을 하도록 한
다. 그래서, 연속적인 받기 호출은 같은 데이터를 반환한다.
MSG_WAITALL
이 플래그는 요구한 양이 다 찰 때까지 작동을 블럭킹하도록 요구한다. 그러나, 만일 신호가 발생하거나, 오류
나 단절이 발생하거나, 혹은받은 데이터가 전에 반환된 데이터와 다른 타입이라면요구한 것보다 적은 데이터라
도 반환한다.
MSG_TRUNC
전달된 버퍼의 길이보다 길더라도 패킷의 실제 길이를 반환한다. 패킷 소켓에서만 유효하다.
MSG_ERRQUEUE
이 플래그는 소켓 오류 큐에 저장된 오류들을 받도록 한다. 오류는 프로토콜(IPv4 IP_RECVERR를위한)에 의존하
는 형식을 갖는 보조 메시지로 전달된다. 사용자는 충분한 크기의 버퍼를 제공해야 한다. 좀더 자세한 정보는
cmsg(3)과 ip(7)을참고하라.
오류를 발생시킨 원래 패킷의 유효 데이터(payload)는 msg_iovec를통해 보통 데이터로 전달된다. 오류를 발 생
시킨 데이터그램의 원래 도착 주소는 msg_name을통해 제공된다.
로 컬 오류에 대해서는 아무런 주소도 전달되지 않는다. (이것은 cmsghdr의멤버인 cmsg_len으로확인할 수 있
다.) 오류가 발생하면, MSG_ERRQUEUE가 msghdr에설정된다. 하나의 에러가 전달된 후, 계류 중인 소켓 오류 는
다 음 저장된 오류를 기반으로 다시 만들어진다. 그리고, 이것은 다음 소켓 연산으로 전달될 것이다. 오류는
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 *SO_EE_OFFENDER(struct sock_extended_err *);
ee_errno는저장된 오류의 오류 번호를 포함한다. ee_origin는오류가 시작됐던 본래 코드이다. 다른 필드들 은
프 로토콜에 의존한다. 매크로 SOCK_EE_OFFENDER는보조 메세지에 주어진 포인터에서 오류가 발생한 네트웍 객체
의 주소에대한 포인터를 반환한다. 만일 이 주소가 알려지지 않았다 면, sockaddr 의 멤 버 인 sa_family 는
AF_UNSPEC 를포함하며 sockaddr의다른 필드들은 정의되지 않는다. 오류를 야기한 패킷은 보통 데이터처럼 전달
된다.
로컬 오류들을 위해, 어떤 주소도 전달되지 않는다. ( 이것은 cmsghdr의멤버인 cmsg_len로확인할 수 있다.) 오
류를 받기 위해, MSG_ERRQUEUE가 msghdr에설정된다.
오류가 전달된 후, 미결인 채로 남아 있던 소켓 오류들은 다음 저장된 오류에 기반하여다시 만들어지고 다음 소
켓 작동시 전달된다.
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_name 과 msg_namelen은소켓이 연결되지 않았으면 목적지 주소를 나타낸다. msg_name은어떤 이름도 원하지 않거나
필요하지 않다면 null 포인터로써 주어진다. msg_iov와 msg_iovlen 필드는 readv(2)처럼 scatter-gather 위치를 가 리
킨 다. msg_controllen의길이를 가지고 있는 msg_control는메세지나 기타 보조 데이터와 관련된 다른 프로토콜 제어를
위한 버퍼를 가리킨다. recvmsg가호출될 때, msg_controllen는 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 받는 버퍼 포인터가 프로세스 주소 공간 이외를 가리키고 있다.
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일
한글 Manpage 프로젝트 (http://man.kldp.org) 2004년 3월 25일
리눅스 메뉴얼 페이지 2002-12-31 RECV(2)
(END)