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 호출은 보통 connected 된 소켓에서만 사용된다. ( connect(2)를 참조해라) 그리고 from 인자를 가진 recvfrom 와 동일하다.
세 루틴 모두 성공적인 완성시 메세지의 길이를 반환한다. 만일 메세지가 제공되는 버퍼보다 더 크다면, 초과된 바이트들은 메세지를 받은 소켓 타입에 의존하여 버려진다.( socket(2)를 참조해라).
만일 어떤 메세지들도 소켓에서 이용할수 없다면, 받는 소켓 호출 함수들은 만일 -1을 반환하고 외부 변수 errno 를 EAGAIN으로 설정하는 경우의 nonblocking이 아니라면 메세지가 도착할때까지 기다린다.( fcntl(2)를 참조해라.) 메세지를 받는 함수들은 보통 요구된 완전한 양을 기다리기 보다는 요구된 양까지 이용할수 있는 데이타를 반환한다.
select(2) 나 poll(2) 호출은 데이터가 더 도착하였는지를 결정하기 위해 사용된다.
받는 함수들을 위한 flags 인자는 다음 값들 중 하나이상의 OR로 구성된다.:
보조 메세지들에서 더 많은 정보를 원하면 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 *);
만일 이 주소가 알려지지 않았다면, sockaddr 의 멤버인 sa_family 는 AF_UNSPEC 를 포함하며 sockaddr 의 다른 필드들은 정의되지 않는다. 에러를 야기한 패킷은 보통 데이터처럼 전달된다.
에러가 전달된후, 미결인채로 남아 있던 소켓 에러들은 다음 큐된 에러에 기반하여 다시 만들어지고 다음 소켓 작동시 전달된다.
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 위치를 가리킨다.
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 는 어떤 데이터도 받지 않았지만 소켓 에러 큐에서 에러가 확장되었다는 것을 가리 킨다.