(original) (raw)

/* $ gcc -Wall peek-udp6.c -o peek-udp6 $ ./peek-udp6 Bytes sent: 14 Received [asdf qwer z] Received [asdf qwer zxcv] Received [asdf qwer zxcv] */ #include #include #include #include #include static const char MSG[] = "asdf qwer zxcv"; static const size_t MSG_LEN = sizeof MSG - 1; int main() { int serv = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0); if(serv < 0) { perror("serv socket()"); return 1; } struct sockaddr_in6 bind_addr; memset(&bind_addr, 0, sizeof bind_addr); bind_addr.sin6_family = AF_INET6; bind_addr.sin6_port = htons(0); bind_addr.sin6_addr = (struct in6_addr)IN6ADDR_LOOPBACK_INIT; if(bind(serv, (struct sockaddr *)&bind_addr, sizeof bind_addr) < 0) { perror("bind(serv)"); return 1; } int cli = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0); if(cli < 0) { perror("cli socket()"); return 1; } if(bind(cli, (struct sockaddr *)&bind_addr, sizeof bind_addr) < 0) { perror("bind(cli)"); return 1; } struct sockaddr_in6 addr; socklen_t addr_len = sizeof addr; if(getsockname(serv, (struct sockaddr *)&addr, &addr_len) < 0) { perror("getsockname()"); return 1; } ssize_t size; size = sendto(cli, MSG, MSG_LEN, 0, (struct sockaddr *)&addr, addr_len); if(size < 0) { perror("sendto()"); return 1; } printf("Bytes sent: %zi\n", size); char buffer[MSG_LEN]; struct msghdr message = { .msg_name = &addr, .msg_namelen = sizeof addr, .msg_iov = (struct iovec [1]){ {.iov_base = buffer, .iov_len = MSG_LEN - 3}, }, .msg_iovlen = 1, }; size = recvmsg(serv, &message, MSG_PEEK); if(size < 0) { perror("short recvmsg(MSG_PEEK)"); return 1; } printf("Received [%.*s]\n", (int)size, buffer); message.msg_iov[0].iov_len = MSG_LEN; size = recvmsg(serv, &message, MSG_PEEK); if(size < 0) { perror("full recvmsg(MSG_PEEK)"); return 1; } printf("Received [%.*s]\n", (int)size, buffer); size = recvmsg(serv, &message, 0); if(size < 0) { perror("full recvmsg(0)"); return 1; } printf("Received [%.*s]\n", (int)size, buffer); return 0; }