epoll中使用recvfrom 获取不到对端的ip和port

一、

epoll 之后的socket recvfrom的时候,需要设置 

        socklen_t socklen = sizeof(struct sockaddr);    //一定要初始化为sizeof,如果为0 则出错
m_data_len = recvfrom(m_fd, m_data, sizeof(m_data), 0, (struct sockaddr*)&m_addr, &socklen);
printf("NetConnector::recv_udp_packet() == m_addr ip = %s,port == %d", 
inet_ntoa(m_addr.sin_addr), ntohs(m_addr.sin_port));

        

        否则获取不到对端的ip和端口

服务器端代码: n=recvfrom(sockfd,msg,MAX_MSG_SIZE,0,(structaddr*)&addr,&addrlen); 客户端向服务器端发送msg后,服务器端能收到,但是,在服务器端不能获取正确的发送方的IP地址。 解决: n=recvfrom(sockfd,msg,MAX_MSG_SIZE,0,(structaddr*)&addr,&addrlen); 在调用recvfrom()之前,加上:addrlen = sizeof(struct sockaddr);即可(之前声明 int addrlen; )。

 

二、客户端和服务器如果需要绑定端口的话,都可以使用bind 进行绑定

       客户端的端口也需要绑定,如果是tcp的话,因为tcp先创建连接,此时就需要绑定端口了

       否则会使用随机的端口和服务器进行连接

三、epoll中每次recv数据时,需要while循环,否则缓冲区满后,有可能不触发epoll_wait

       Server端调用recv函数, socket数据没有完全读出,  后导致Server端协议栈满,建议用while(recv>0)将所有数据全部读出。

       例如

        while(1)

       {

                  recv(data,len )

                  push_to_mypacket(data);    //此时即使push 出错,也只能continue,不能return,否则会导致协议栈满

       }

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在C语言,可以使用epoll来实现多个客户端转发到多服务器的网络编程。下面是一个简单的示例代码,演示如何使用epoll来实现这个功能```c #include <stdio.h> #include <stdlib> #include <string.h> #include <unistd.h> <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/epoll.h> #define MAX_EVENTS 10 #define BUFFER_SIZE 1024 int main() { int listen_fd, epoll_fd; struct sockaddr_in server_addr, client_addr; struct epoll_event events[MAX_EVENTS]; char buffer[BUFFER_SIZE]; // 创建监听套接字 listen_fd = socket(AF_INET, SOCK_STREAM, 0); if (listen_fd == -1) { perror("socket"); exit(1); } // 设置服务器地址和端口 memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(8888); server_addr.sin_addr.s_addr = INADDR_ANY; // 绑定监听套接字到服务器地址和端口 if (bind(listen_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) { perror("bind"); exit(1); } // 开始监听连接请求 if (listen(listen_fd, 10) == -1) { perror("listen"); exit(1); } // 创建epoll实例 epoll_fd = epoll_create(MAX_EVENTS); if (epoll_fd == -1) { perror("epoll_create"); exit(1); } // 将监听套接字添加到epoll实例,监听读事件 struct epoll_event event; event.events = EPOLLIN; event.data.fd = listen_fd; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_fd, &event) == -1) { perror("epoll_ctl"); exit(1); } while (1) { int num_events = epoll_wait(epoll_fd, events, MAX_EVENTS, -1); if (num_events == -1) { perror("epoll_wait"); exit(1); } for (int i = 0; i < num_events; i++) { int fd = events[i].data.fd; // 如果是监听套接字上有读事件发生,说明有新的客户端连接请求 if (fd == listen_fd) { socklen_t client_addr_len = sizeof(client_addr); int client_fd = accept(listen_fd, (struct sockaddr*)&client_addr, &client_addr_len); if (client_fd == -1) { perror("accept"); exit(1); } printf("New client connected: %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); // 将新的客户端套接字添加到epoll实例,监听读事件 event.events = EPOLLIN; event.data.fd = client_fd; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &event) == -1) { perror("epoll_ctl"); exit(1); } } // 如果是客户端套接字上有读事件发生,说明有客户端发送数据到服务器 else { int num_bytes = read(fd, buffer, BUFFER_SIZE); if (num_bytes == -1) { perror("read"); exit(1); } if (num_bytes == 0) { printf("Client disconnected\n"); close(fd); epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL); } else { // 根据转发策略选择目标服务器,并将数据转发给相应的服务器 // ... } } } } close(listen_fd); close(epoll_fd); return 0; } ``` 上面的代码创建了一个监听套接字,并使用epoll来监听读事件。当有新的客户端连接时,将客户端套接字添加到epoll实例。当客户端套接字上有读事件发生时,读取数据并根据转发策略选择目标服务器进行转发。请注意,示例代码的转发策略部分需要根据实际需求进行实现。 希望以上示例能帮助到你实现多个客户端转发到多个服务器的网络编程功能。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值