C UDP epoll仅从单个端口检测数据
我试图实现一个程序来理解UDP EPOL的真正工作原理。我已经完成了如下代码。这适用于单个插座。但是,当我尝试使用多个套接字时(例如10000、10001、10002、10003的4个套接字),它只检测最后一个套接字上的数据(这里是第四个,即10003)。有人看过我的代码并告诉我这里有什么问题吗C UDP epoll仅从单个端口检测数据,c,linux,sockets,epoll,C,Linux,Sockets,Epoll,我试图实现一个程序来理解UDP EPOL的真正工作原理。我已经完成了如下代码。这适用于单个插座。但是,当我尝试使用多个套接字时(例如10000、10001、10002、10003的4个套接字),它只检测最后一个套接字上的数据(这里是第四个,即10003)。有人看过我的代码并告诉我这里有什么问题吗 #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <s
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/epoll.h>
#define MAX_EVENTS 20
#define MAXLINE 1024
int get_new_socket(int port)
{
int sockfd;
struct sockaddr_in servaddr;
if ((sockfd = socket(PF_INET, SOCK_DGRAM /*|SOCK_NONBLOCK|SOCK_CLOEXEC*/, IPPROTO_UDP)) < 0 ) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(port);
if (bind(sockfd, (const struct sockaddr *)&servaddr,
sizeof(servaddr)) < 0 )
{
perror("bind failed");
exit(EXIT_FAILURE);
}
return sockfd;
}
void recv_send_data(int sockfd)
{
char buffer[MAXLINE];
char *hello = "Hello from server";
struct sockaddr_in cliaddr;
int ret;
memset(&cliaddr, 0, sizeof(cliaddr));
int len = sizeof(cliaddr), n = 17;
n = recvfrom(sockfd, (char *)buffer, MAXLINE, 0, (struct sockaddr *)&cliaddr, &len);
perror("recvfrom");
buffer[n] = '\0';
printf("[%d]Client : %s\n", n, buffer);
ret = sendto(sockfd, (const char *)hello, 17, 0, (const struct sockaddr *)&cliaddr, len);
printf("sent back to client.[%d]\n", ret);
}
int main(int argc, char *argv[]) {
struct epoll_event ev, events[MAX_EVENTS];
int listen_sock, nfds, epollfd, n;
int start_port = 10000;
for(n = start_port; n < start_port + 4; n++) {
listen_sock = get_new_socket(n);
printf("Created socket[%d] for port %d\n", listen_sock, n);
epollfd = epoll_create1(0);
if (epollfd == -1) {
perror("epoll_create");
exit(EXIT_FAILURE);
}
ev.events = EPOLLIN;
ev.data.fd = listen_sock;
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev) == -1) {
perror("epoll_ctl: listen_sock");
exit(EXIT_FAILURE);
}
}
for (;;) {
printf("Waiting on epoll\n");
nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
if (nfds == -1) {
perror("epoll_pwait");
exit(EXIT_FAILURE);
}
printf("EPOLL wait over; processing...\n");
for (n = 0; n < nfds; ++n) {
if (events[n].data.fd == listen_sock) {
printf("Data received on: %d, listen_sock: %d\n", events[n].data.fd, listen_sock);
recv_send_data(listen_sock);
}
}
sleep(1);
}
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义最大事件20
#定义MAXLINE 1024
int get_new_插槽(int端口)
{
int-sockfd;
servaddr中的结构sockaddr_;
如果((sockfd=socket(PF_INET,SOCK_DGRAM/*| SOCK_NONBLOCK | SOCK_CLOEXEC*/,IPPROTO_UDP))<0){
perror(“套接字创建失败”);
退出(退出失败);
}
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin\u addr.s\u addr=INADDR\u ANY;
servaddr.sinu端口=htons(端口);
if(bind(sockfd,(const struct sockaddr*)和servaddr,
sizeof(servaddr))<0)
{
perror(“绑定失败”);
退出(退出失败);
}
返回sockfd;
}
无效接收发送数据(int sockfd)
{
字符缓冲区[MAXLINE];
char*hello=“来自服务器的hello”;
cliaddr中的结构sockaddr_;
int ret;
memset(&cliaddr,0,sizeof(cliaddr));
int len=sizeof(cliaddr),n=17;
n=recvfrom(sockfd,(char*)缓冲区,MAXLINE,0,(struct sockaddr*)和cliaddr,&len);
perror(“recvfrom”);
缓冲区[n]=“'\0';
printf(“[%d]客户端:%s\n”,n,缓冲区);
ret=sendto(sockfd,(const char*)你好,17,0,(const struct sockaddr*)和cliaddr,len);
printf(“发送回客户端。[%d]\n”,ret);
}
int main(int argc,char*argv[]){
结构epoll_事件ev,事件[最大事件];
int listen_sock,nfds,epollfd,n;
int start_端口=10000;
用于(n=开始\u端口;n<开始\u端口+4;n++){
listen\u sock=获取新的\u套接字(n);
printf(“为端口%d\n创建了套接字[%d],侦听\u sock,n);
epollfd=epoll_create1(0);
如果(epollfd==-1){
perror(“epoll_create”);
退出(退出失败);
}
ev.events=依泊林;
ev.data.fd=监听_sock;
if(epoll\u ctl(epollfd、epoll\u ctl\u ADD、listen\u sock和ev)=-1){
perror(“epoll_ctl:listen_sock”);
退出(退出失败);
}
}
对于(;;){
printf(“等待epoll\n”);
nfds=epoll\u等待(epollfd,事件,最大事件,-1);
如果(nfds==-1){
佩罗尔(epoll_pwait);
退出(退出失败);
}
printf(“EPOLL等待;处理…\n”);
对于(n=0;n
为什么要为每个FD创建epoll。您只需要使用epoll\u create and use for all fd创建一个epoll<代码>epollfd=epoll_create1(0)代码>将这一行移到loop.Oops上面,明白了。。。谢谢你@MohitJain