이 름
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 [AT] soback.net>
2000년 12월 11일
한 글 Manpage 프 로 젝
트 (http://man.kldp.org) 2004년 3월
25일