EPOLL 监听 UDP
时间: 2023-10-14 12:40:21 浏览: 49
EPOLL 可以用于监听 UDP。使用 EPOLL 监听 UDP 协议的过程与 TCP 类似,但是需要注意的是,在监听 UDP 时,需要将监听套接字设置为非阻塞模式,因为 UDP 是无连接的,所以如果将监听套接字设置为阻塞模式,程序会一直阻塞在 recvfrom 函数上,无法处理其他事件。
在使用 EPOLL 监听 UDP 时,需要将监听套接字注册到 EPOLL 中,并设置相应的事件(如 EPOLLIN 表示数据可读)。当有数据到来时,EPOLL 会通知程序进行处理。在处理 UDP 数据时,需要使用 recvfrom 函数获取数据,并通过发送方的 IP 地址和端口号来确定数据的来源。
相关问题
EPOLL 监听 UDP 代码示例
下面是一个简单的用 EPOLL 监听 UDP 的代码示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define MAX_EVENTS 10
int main() {
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1) {
perror("socket error");
exit(1);
}
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(8888);
if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
perror("bind error");
exit(1);
}
int epollfd = epoll_create(1);
if (epollfd == -1) {
perror("epoll_create error");
exit(1);
}
struct epoll_event ev, events[MAX_EVENTS];
ev.events = EPOLLIN;
ev.data.fd = sockfd;
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, sockfd, &ev) == -1) {
perror("epoll_ctl error");
exit(1);
}
while (1) {
int n = epoll_wait(epollfd, events, MAX_EVENTS, -1);
if (n == -1) {
perror("epoll_wait error");
exit(1);
}
for (int i = 0; i < n; i++) {
if (events[i].data.fd == sockfd) {
struct sockaddr_in cli_addr;
socklen_t len = sizeof(cli_addr);
char buf[1024];
int nrecv = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&cli_addr, &len);
if (nrecv == -1) {
perror("recvfrom error");
exit(1);
}
buf[nrecv] = '\0';
printf("Received %d bytes from %s:%d: %s\n", nrecv, inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port), buf);
}
}
}
close(epollfd);
close(sockfd);
return 0;
}
```
在上面的代码中,我们先创建了一个 UDP 套接字,并绑定到本地地址和端口上。然后创建了一个 EPOLL 对象,并将监听套接字注册到其中,并设置事件类型为 EPOLLIN,表示可以读取数据。最后在 while 循环中不断调用 epoll_wait 等待事件发生,并在事件发生时进行处理(在这里只处理了来自监听套接字的数据)。
使用EPOLL 监听 UDP 接收的代码
好的,以下是一个使用EPOLL监听UDP接收的示例代码:
```
#include <sys/epoll.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define MAX_EVENTS 10
int main() {
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(8080);
bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
int epfd = epoll_create1(0);
struct epoll_event event, events[MAX_EVENTS];
event.data.fd = sockfd;
event.events = EPOLLIN;
epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &event);
while (1) {
int n = epoll_wait(epfd, events, MAX_EVENTS, -1);
for (int i = 0; i < n; i++) {
if (events[i].data.fd == sockfd) {
char buffer[1024];
struct sockaddr_in client_addr;
socklen_t client_len = sizeof(client_addr);
int len = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&client_addr, &client_len);
printf("Received %d bytes from %s:%d\n", len, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
}
}
}
close(epfd);
close(sockfd);
return 0;
}
```
这个示例代码与之前的示例代码非常相似,但使用了epoll_create1()函数来创建epoll实例,并设置了EPOLL_CLOEXEC标志,以在执行exec()函数时自动关闭epoll实例。在主循环中,我们调用epoll_wait()函数进行监听事件,如果UDP套接字有事件发生(EPOLLIN),则调用recvfrom()函数接收UDP数据包。与之前的示例代码相比,这个代码更加健壮和安全。
相关推荐
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)