/* SPDX-License-Identifier: MIT */ /* * Simple test case showing using sendmsg and recvmsg through io_uring */ #include #include #include #include #include #include #include #include #include #include "liburing.h" static const char *str = "This is a test of sendmsg and recvmsg over io_uring!"; #define MAX_MSG 128 #define PORT 10200 #define HOST "127.0.0.1" static int recv_prep(struct io_uring *ring, struct iovec *iov) { struct sockaddr_in saddr; struct msghdr msg; struct io_uring_sqe *sqe = NULL; int sockfd, ret; int val = 1; memset(&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = htonl(INADDR_ANY); saddr.sin_port = htons(PORT); sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { perror("socket"); return 1; } val = 1; setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val)); setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); ret = bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)); if (ret < 0) { perror("bind"); goto err; } memset(&msg, 0, sizeof(msg)); msg.msg_namelen = sizeof(struct sockaddr_in); msg.msg_iov = iov; msg.msg_iovlen = 1; sqe = io_uring_get_sqe(ring); if (!sqe) printf("sqe is null \r\n"); io_uring_prep_recvmsg(sqe, sockfd, &msg, 0); ret = io_uring_submit_and_wait(ring, 1); if (ret <= 0) { printf("submit failed: %d\n", ret); goto err; } printf("ret is %d\r\n", ret); close(sockfd); return 0; err: close(sockfd); return 1; } int main(int argc, char *argv[]) { pid_t p; char buf[MAX_MSG + 1]; struct iovec iov = { .iov_base = buf, .iov_len = sizeof(buf) - 1, }; struct io_uring_sqe *sqe; struct io_uring_cqe *cqe; struct io_uring ring; int ret; ret = io_uring_queue_init(1, &ring, 0); if (ret) { printf("queue init failed: %d\n", ret); return 0; } p = fork(); switch (p) { case -1: perror("fork"); exit(2); case 0: {//child recv_prep(&ring, &iov); //sleep(500000); break; } default: printf("pid: %d\n", p); //recv_prep(&ring, &iov); sleep(50000); return 0; } }