RECV(2)

명칭
recv, recvfrom, recvmsg - 소켓으로부터 메세지를 수신한다

프로그램 라이브러리
libc

서식
<sys/types.h> <sys/socket.h> ssize_t recv(int s, void *buf, size_t len, int flags) ssize_t recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen) ssize_t recvmsg(int s, struct msghdr *msg, int flags)

해설
recvfrom() (와)과 recvmsg() (은)는, 소켓으로부터의 메세지를 수신하는데 사용됩니다. 소켓이 접속 지향인지 어떤지에 관계없이, 소켓상의 데이터를 수신하는데 사용할 수 있습니다.

from 하지만 nil 가 아니고, 소켓이 접속 지향이 아닌 경우, 여기에는 메세지의 소스 주소가 보존됩니다. fromlen (은)는 「값 - 결과」파라미터이며, from 에 대응하는 버퍼의 사이즈에 초기화되어 귀가시에는 보존된 주소의 실제의 사이즈를 나타내도록(듯이) 변경됩니다.

recv() 호출은, 통상 접속되었다 소켓상에서만 사용되고 (connect(2) (을)를 참조), from 파라미터에 nil 를 지정했다 recvfrom() (와)과 동일합니다. 이것은 장황해서, 장래의 릴리스에서는 서포트되지 않을 가능성이 있습니다.

이것들 3 개의 routine는 정상적으로 완료한다고 메세지의 길이를 돌려줍니다. 메세지가 너무 길어 지정의 버퍼에 들어가지 않는 경우, 메세지를 수신한 소켓의 타입에 따라서는 초과 분의 바이트가 파기되는 일이 있습니다 (socket(2) (을)를 참조).

소켓에 메세지가 없는 경우는, 소켓이 비블로킹 (fcntl(2) (을)를 참조)의 경우를 제외해, 호출은 메세지가 도착하는 것을 기다립니다. 소켓이 비블로킹의 경우, 값 -1 이 돌려주어져 외부 변수 errno 하지만 EAGAIN (으)로 설정됩니다. 통상, 수신 호출은 요구된 양을 수신할 때까지 기다리지 않고 , 요구된 양을 상한으로서 얻을 수 있던 데이터를 돌려줍니다. 이 동작은, getsockopt(2) 그리고 해설되고 있는 소켓 레벨의 옵션 SO_RCVLOWAT 및 SO_RCVTIMEO 에 의해 영향을 받습니다.

다음의 데이터가 언제 도착하는지를 판정하려면 select(2) 호출을 사용할 수가 있습니다.

recv 호출에의 flags 인수는, 다음의 값의 1 개 또는 복수의 논리합 (or) (으)로부터 완성됩니다.
MSG_OOB | 프로세스 대역외 데이터
MSG_PEEK | 착신 메세지의 들여다 보고 (peek)
MSG_WAITALL | 요구의 완전한 실행, 또는 에러를 기다린다

MSG_OOB 플래그는 대역외 데이터의 수신을 요구해, 통상의 데이터 스트림으로부터는 수신하지 않습니다. 급송 데이터를 통상의 데이터 기다리는 행렬의 선두에 배치하는 프로토콜도 있습니다만, 이 플래그는 그러한 프로토콜에서는 사용할 수 없습니다. MSG_PEEK 플래그는 수신 기다리는 행렬의 선두로부터 데이터를 제거하는 일 없이, 그 데이터를 돌려줍니다. 따라서, 후속의 수신 호출은 같은 데이터 (을)를 돌려줍니다. MSG_WAITALL 플래그는 요구가 완전하게 채워질 때까지 블록 하도록(듯이) 요구합니다. 그러나, 시그널이 포착되었을 경우, 에러 또는 절단이 발생했을 경우, 또는 수신하는 다음의 데이터가 돌려주어진 타입과 다르다 경우, 호출은 요구되었던 것보다 적은 데이터를 돌려줄 가능성이 있습니다.

recvmsg() 호출은, 직접 지정되는 파라미터의 수를 최소로 하기 위해서(때문에) msghdr 구조체를 사용합니다. 이 구조체는 <sys/socket.h> 그리고 정의되고 있도록(듯이), 다음의 형식이 되어 있습니다.

    struct msghdr {
    	caddr_t	msg_name;	/* 주소(옵션) */
    	u_int	msg_namelen;	/* 주소의 사이즈 */
    	struct	iovec *msg_iov;	/* 스캐타/개더 배열 */
    	u_int	msg_iovlen;	/* msg_iov 의 요소수 */
    	caddr_t	msg_control;	/* 보조 데이터, 후술 */
    	u_int	msg_controllen; /* 보조 데이터의 버퍼장 */
    	int	msg_flags;	/* 수신된 메세지상의 플래그 */
    };

여기서 msg_name (와)과 msg_namelen (은)는, 소켓이 접속되어 있지 않은 경우에, 행선지 주소를 지정합니다. 이름을 요구하지 않는 경우나 필요하지 않은 경우, msg_name (은)는 NULL 포인터로서 지정할 수 있습니다. msg_iov (와)과 msg_iovlen 하 read(2) 그리고 설명되고 있도록(듯이) 스캐타/개더의 장소를 기술합니다. msg_control (은)는, 길이가 msg_controllen 의, 다른 프로토콜 제어에 관련하는 메세지 또는 그 외의 각종 보조 데이터용의 버퍼를 가리키고 있습니다. 메세지는 다음의 형식입니다.

    struct cmsghdr {
    	u_int	cmsg_len;	/* 데이터 바이트 카운트, hdr 를 포함한다 */
    	int	cmsg_level;	/* 메세지를 생성한 프로토콜 */
    	int	cmsg_type;	/* 프로토콜에 고유의 타입 */
    /*	u_char	cmsg_data[]; 가 후에 계속된다 */
    };

예를 들어, 이것을 사용해 XNS/SPP 에 대해 데이터 스트림의 변화를 알 수가 있습니다. 또, ISO 에 대해 accept() 호출의 직후에, 데이터 버퍼를 수반하지 않고 recvmsg 를 요구해, 유저 접속 요구 데이터를 얻을 수 있겠지요.

오픈된 파일 기술자는 이것으로 AF_UNIX 도메인 소켓용의 보조 데이터로서 인도해져 그 때, cmsg_level 하지만 SOL_SOCKET (으)로 설정되어 cmsg_type 하지만 SCM_RIGHTS (으)로 설정됩니다.

SCM_CREDS 의 cmsg_type (을)를 사용해, 프로세스의 인증 정보를 AF_UNIX 도메인 소켓용의 보조 데이터로서 건네줄 수도 있습니다. 이 케이스에서는, cmsg_data (은)는, 구조체 cmsgcred 일 필요가 있습니다. 이것은 다음과 같이 <sys/socket.h> 안에서 정의되고 있습니다.

    struct cmsgcred {
    	pid_t	cmcred_pid;		/* 송신 프로세스의 PID */
    	uid_t	cmcred_uid;		/* 송신 프로세스의 열매 UID */
    	uid_t	cmcred_euid;		/* 송신 프로세스의 실효 UID */
    	gid_t	cmcred_gid;		/* 송신 프로세스의 열매 GID */
    	short	cmcred_ngroups;		/* 그룹의 수 */
    	gid_t	cmcred_groups[CMGROUP_MAX];	/* 그룹 */
    };

커널은 송신 프로세스의 인증 정보를 기입해, 그것을 수신측에 전달합니다.

msg_flags 필드는 수신이 끝난 메세지에 따라 귀가시로 설정됩니다. MSG_EOR (은)는 end-of-record, 즉 돌려주어진 데이터로 레코드가 완결하고 있는 것을 나타냅니다 (일반적으로는, 타입 SOCK_SEQPACKET 의 소켓과 함께 사용됩니다). MSG_TRUNC (은)는, 제공된 버퍼보다 데이터 그램이 컸기 때문에, 데이터 그램의 뒤의 부분을 잘라 버릴 수 있던 것을 나타냅니다. MSG_CTRUNC (은)는, 보조 데이터용의 버퍼내의 공간의 부족을 위해서(때문에) 얼마인가의 제어 데이터가 잘라 버릴 수 있던 것을 나타냅니다. MSG_OOB (은)는, 급송 또는 대역외 데이터가 수신된 것을 나타냅니다.

반환값
이러한 호출은 수신한 바이트수를 돌려주어, 에러가 일어났을 경우는 -1 을 돌려줍니다.

에러
호출은 다음의 경우에 실패합니다.

[EBADF]
    인수 s 하지만 유효한 기술자가 아닙니다.

[ENOTCONN]
    소켓은 접속 지향 프로토콜과 연결시킬 수 있고 있습니다만, 접속되고 있지 않습니다 (connect(2) (와)과 accept(2) (을)를 참조).

[ENOTSOCK]
    인수 s (은)는 소켓을 참조하고 있지 않습니다.

[EAGAIN]
    소켓이 비블로킹과 마크 되고 있을 때, 수신 조작으로 블록 했습니다. 혹은, 수신 타임 아웃이 설정되어 있어, 데이터가 수신되기 전에 타임 아웃이 되었습니다.

[EINTR]
    데이터가 수신 가능하게 되기 전에, 수신이 시그널에 의해 비율 붐비어졌습니다.

[EFAULT]
    수신 버퍼 포인터가, 프로세스에 할당할 수 있었던 address 공간의 범위외를 가리키고 있습니다.

관련 항목
fcntl(2), getsockopt(2), read(2), select(2), socket(2)

역사
recv() 함수는 4.2BSD 그리고 등장했습니다.