recvmmsg(2) - wariua/manpages-ko GitHub Wiki
recvmmsg - ์์ผ์์ ์ฌ๋ฌ ๋ฉ์์ง ๋ฐ๊ธฐ
#define _GNU_SOURCE /* feature_test_macros(7) ์ฐธ๊ณ */
#include <sys/socket.h>
int recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen,
int flags, struct timespec *timeout);
recvmmsg()
์์คํ
ํธ์ถ์ recvmsg(2)๋ฅผ ํ์ฅํ ๊ฒ์ด๋ค. ํธ์ถ์๊ฐ ์์คํ
ํธ์ถ ํ ๋ฒ์ผ๋ก ์์ผ์์ ์ฌ๋ฌ ๋ฉ์์ง๋ฅผ ์์ ํ ์ ์๊ฒ ํด ์ค๋ค. (์ผ๋ถ ์์ฉ์์ ์ฑ๋ฅ์ ์ด์ ์ด ์๋ค.) ๋ recvmsg(2)๋ฅผ ํ์ฅํด์ ์์ ๋์์ ํ์์์์ ์ง์ํ๋ค.
sockfd
์ธ์๋ ๋ฐ์ดํฐ๋ฅผ ์์ ํ ์์ผ์ ํ์ผ ๋์คํฌ๋ฆฝํฐ์ด๋ค.
msgvec
์ธ์๋ mmsghdr
๊ตฌ์กฐ์ฒด ๋ฐฐ์ด์ ๋ํ ํฌ์ธํฐ์ด๋ค. ์ด ๋ฐฐ์ด์ ํฌ๊ธฐ๋ฅผ vlen
์ ์ง์ ํ๋ค.
mmsghdr
๊ตฌ์กฐ์ฒด๋ <sys/socket.h>
์ ๋ค์์ฒ๋ผ ์ ์๋ผ ์๋ค.
struct mmsghdr {
struct msghdr msg_hdr; /* ๋ฉ์์ง ํค๋ */
unsigned int msg_len; /* ์์ ํ ๋ฐ์ดํธ ์ */
};
msg_hdr
ํ๋๋ recvmsg(2)์์ ๊ธฐ์ ํ๋ msghdr
๊ตฌ์กฐ์ฒด์ด๋ค. msg_len
ํ๋๋ ๊ทธ ํญ๋ชฉ์ ๋ฉ์์ง์ ๋ฐํ ๋ฐ์ดํธ ์์ด๋ค. ์ด ํ๋์ ๊ฐ์ ๊ทธ ํค๋์ ๋ํด ๋ฐ๋ก recvmsg(2)๋ฅผ ํธ์ถํ์ ๋์ ๋ฐํ ๊ฐ๊ณผ ๊ฐ๋ค.
flags
์ธ์๋ OR ํ ํ๋๊ทธ๋ค์ ๋ด๋๋ค. recvmsg(2)์ ๊ธฐ๋ก๋ ๊ฒ๋ค์ ๋ํด ๋ค์ ํ๋๊ทธ๊ฐ ์๋ค.
-
MSG_WAITFORONE
(๋ฆฌ๋ ์ค 2.6.34๋ถํฐ) - ์ฒซ ๋ฒ์งธ ๋ฉ์์ง๋ฅผ ์์ ํ ํ์
MSG_DONTWAIT
์ ์ผ ๋ค.
timeout
์ธ์๋ struct timespec
(clock_gettime(2) ์ฐธ๊ณ )์ ๊ฐ๋ฆฌํค๋ฉฐ ์์ ๋์์ ํ์์์(์ด ๋ํ๊ธฐ ๋๋
ธ์ด)์ ์ง์ ํ๋ค. (ํ์ง๋ง BUGS ์ฐธ๊ณ .) (์ด ์๊ฐ์ ์์คํ
ํด๋ญ ํด์๋์ ๋ฐ๋ผ ์ฌ๋ฆผ ํ๊ฒ ๋๋ฉฐ ์ปค๋ ์ค์ผ์ค๋ง ์ง์ฐ๋ ์๊ธฐ ๋๋ฌธ์ ๊ทธ ๋ธ๋ก ์๊ฐ์ ์ฝ๊ฐ ๋๊ธธ ์๋ ์๋ค.) timeout
์ด NULL์ด๋ฉด ๋์์ด ์์ํ ๋ธ๋ก ํ๋ค.
๋ธ๋กํน recvmmsg()
ํธ์ถ์ vlen
๊ฐ ๋ฉ์์ง๋ฅผ ์์ ํ๊ฑฐ๋ ํ์์์์ด ๋ง๋ฃ๋ ๋๊น์ง ๋ธ๋ก ํ๋ค. ๋
ผ๋ธ๋กํน ํธ์ถ์ ๊ฐ๋ฅํ ๋ง์ ๋ฉ์์ง๋ฅผ (vlen
์ผ๋ก ์ง์ ํ ํ๊ณ๊น์ง) ์ฝ์ด ๋ค์ด๊ณ ์ ์ฆ์ ๋ฐํํ๋ค.
recvmmsg()
์์ ๋ฐํ ์ msgvec
์ ์ฐ์๋ ํญ๋ชฉ๋ค์ด ๊ฐ ์์ ๋ฉ์์ง์ ๋ํ ์ ๋ณด๋ฅผ ๋ด๋๋ก ๊ฐฑ์ ๋์ด ์๋ค. msg_len
์ ์์ ๋ฉ์์ง์ ํฌ๊ธฐ๋ฅผ ๋ด๋๋ค. ๊ทธ๋ฆฌ๊ณ msg_hdr
์ ํ์ ํ๋๋ค์ด recvmsg(2)์์ ๊ธฐ์ ํ๋ ๋๋ก ๊ฐฑ์ ๋์ด ์๋ค. ํธ์ถ์ ๋ฐํ ๊ฐ์ ๊ฐฑ์ ๋ msgvec
ํญ๋ชฉ ๊ฐ์๋ฅผ ๋ํ๋ธ๋ค.
์ฑ๊ณต ์ recvmmsg()
๋ msgvec
์ ๋ฐ์ ๋ฉ์์ง ๊ฐ์๋ฅผ ๋ฐํํ๋ค. ์ค๋ฅ ์ -1์ ๋ฐํํ๋ฉฐ ์ค๋ฅ๋ฅผ ๋ํ๋ด๋๋ก errno
๋ฅผ ์ค์ ํ๋ค.
์ค๋ฅ๋ค์ด recvmsg(2)์์์ ๊ฐ๋ค. ์ถ๊ฐ๋ก ๋ค์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์๋ค.
EINVAL
-
timeout
์ด ์ ํจํ์ง ์๋ค.
BUGS๋ ์ฐธ๊ณ .
๋ฆฌ๋
์ค 2.6.33์์ recvmmsg()
์์คํ
ํธ์ถ์ด ์ถ๊ฐ๋์๋ค. glibc ๋ฒ์ 2.12์์ ์ง์์ด ์ถ๊ฐ๋์๋ค.
recvmmsg()
๋ ๋ฆฌ๋
์ค ์ ์ฉ์ด๋ค.
timeout
์ธ์๊ฐ ์๋ ๋๋ก ๋์ํ์ง ์๋๋ค. ๊ฐ ๋ฐ์ดํฐ๊ทธ๋จ ์์ ํ์๋ง ํ์์์์ ํ์ธํ๋ฉฐ, ๋ฐ๋ผ์ ํ์์์ ๋ง๋ฃ ์ ์ vlen-1
๊ฐ๊น์ง ๋ฐ์ดํฐ๊ทธ๋จ์ ์์ ํ๊ณ ์ ์ดํ ๋๋ ๋ฐ์ดํฐ๊ทธ๋จ์ ์์ ํ์ง ์์ผ๋ฉด ํธ์ถ์ด ์์ํ ๋ธ๋ก ํ๊ฒ ๋๋ค.
์ต์ ํ ๊ฐ ๋ฉ์์ง๋ฅผ ๋ฐ์ ํ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ํธ์ถ์ด ์ฑ๊ณตํ๊ณ ๋ฐ์ ๋ฉ์์ง ์๋ฅผ ๋ฐํํ๋ค. ์ค๋ฅ ์ฝ๋๋ ์ด์ด์ง๋ recvmmsg()
์์ ๋ฐํ๋๋๋ก ๋ผ ์๋ค. ํ์ง๋ง ํ์ฌ ๊ตฌํ์์๋ ์์ผ์์์ ๊ด๋ จ ์๋ ๋คํธ์ํฌ ์ด๋ฒคํธ(๊ฐ๋ น ICMP ํจํท ์
๋ ฅ) ๋๋ฌธ์ ๊ทธ ์ฌ์ด์ ์ค๋ฅ ์ฝ๋๊ฐ ๋ฎ์ด ์จ์ง ์ ์๋ค.
๋ค์ ํ๋ก๊ทธ๋จ์์๋ recvmmsg()
๋ฅผ ์ฌ์ฉํด ์์ผ์์ ์ฌ๋ฌ ๋ฉ์์ง๋ฅผ ๋ฐ์์ ์ฌ๋ฌ ๋ฒํผ์ ์ ์ฅํ๋ค. ๋ชจ๋ ๋ฒํผ๊ฐ ์ฐจ๊ฑฐ๋ ์ง์ ํ ํ์์์์ด ๋ง๋ฃ๋ ๊ฒฝ์ฐ์ ํธ์ถ์ด ๋ฐํํ๋ค.
๋ค์ ๋ช ๋ น์ ๋์๋ฅผ ๋ด์ UDP ๋ฐ์ดํฐ๊ทธ๋จ์ ์ฃผ๊ธฐ์ ์ผ๋ก ์์ฑํ๋ค.
$ while true; do echo $RANDOM > /dev/udp/127.0.0.1/1234;
sleep 0.25; done
๊ทธ ๋ฐ์ดํฐ๊ทธ๋จ๋ค์ ์์ ์์ฉ์ด ์ฝ์ด ๋ค์ฌ์ ๋ค์๊ณผ ๊ฐ์ด ์ถ๋ ฅํ๋ค.
$ ./a.out
5 messages received
1 11782
2 11345
3 304
4 13514
5 28421
#define _GNU_SOURCE
#include <netinet/ip.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
int
main(void)
{
#define VLEN 10
#define BUFSIZE 200
#define TIMEOUT 1
int sockfd, retval, i;
struct sockaddr_in addr;
struct mmsghdr msgs[VLEN];
struct iovec iovecs[VLEN];
char bufs[VLEN][BUFSIZE+1];
struct timespec timeout;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1) {
perror("socket()");
exit(EXIT_FAILURE);
}
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr.sin_port = htons(1234);
if (bind(sockfd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
perror("bind()");
exit(EXIT_FAILURE);
}
memset(msgs, 0, sizeof(msgs));
for (i = 0; i < VLEN; i++) {
iovecs[i].iov_base = bufs[i];
iovecs[i].iov_len = BUFSIZE;
msgs[i].msg_hdr.msg_iov = &iovecs[i];
msgs[i].msg_hdr.msg_iovlen = 1;
}
timeout.tv_sec = TIMEOUT;
timeout.tv_nsec = 0;
retval = recvmmsg(sockfd, msgs, VLEN, 0, &timeout);
if (retval == -1) {
perror("recvmmsg()");
exit(EXIT_FAILURE);
}
printf("%d messages received\n", retval);
for (i = 0; i < retval; i++) {
bufs[i][msgs[i].msg_len] = 0;
printf("%d %s", i+1, bufs[i]);
}
exit(EXIT_SUCCESS);
}
clock_gettime(2), recvmsg(2), sendmmsg(2), sendmsg(2), socket(2), socket(7)
2019-03-06