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);
만일 from이 NULL이 아니고 소켓이 연결 지향형이 아니라면, 메세지의 본래 주소가 채워진다. 인자 fromlen은 값-결과 변수이며 from과 관련된 버퍼의 크기로 초기화되며, 반환시 저장되는 주소의 실제 크기를 가리키는 값으로 수정된다.
recv 호출은 보통 연결된 소켓에서만 사용된다. ( connect(2)를 참조하라) 그리고 from 인자를 가진 recvfrom과 동일하다.
소켓에 메시지가 없다면, 메시지를 받는 호출은 메시지가 들어올때까지 기다리게되며, 만약 소켓이 넌블럭킹( fcntl(2) 참조)이었다면 결과값은 -1이 되고 errno를 EAGAIN으로 설정한다. 일반적으로 메시지를 받는 호출들은 요구된 양을 모두 채우며 기다리기 보다는 채워진 양을 리턴한다.
select(2) 나 poll(2) 호출은 데이터가 더 도착하였는지를 결정하기 위해 사용된다.
받는 함수들을 위한 flags 인자는 다음 값들 중 하나 이상의 OR로 구성된다.:
오류를 발생시킨 원래 패킷의 유효 데이터(payload)는 msg_iovec를 통해 보통 데이터로 전달된다. 오류를 발생시킨 데이터그램의 원래 도착 주소는 msg_name을 통해 제공된다.
#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 *);
오류가 전달된 후, 미결인 채로 남아 있던 소켓 오류들은 다음 저장된 오류에 기반하여 다시 만들어지고 다음 소켓 작동시 전달된다.
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는 어떤 데이터도 받지 않았지만 소켓 오류 큐에서 오류가 확장되었다는 것을 나타낸다.