用C++ 技术加epoll,来实现一个服务代码
时间: 2024-03-19 13:43:11 浏览: 27
好的,以下是一个基于 epoll 技术的 C++ 服务端代码示例,可以实现多个客户端的连接和消息交互:
```cpp
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
using namespace std;
const int MAX_EVENTS = 100;
const int MAX_CLIENTS = 10;
const int BUF_SIZE = 1024;
int main(int argc, char *argv[]) {
int listen_fd, conn_fd, epoll_fd, n_events;
struct sockaddr_in serv_addr, cli_addr;
struct epoll_event event, events[MAX_EVENTS];
char buf[BUF_SIZE];
int n_ready;
// 初始化服务端地址
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5555);
// 创建监听套接字
if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket error");
exit(EXIT_FAILURE);
}
// 绑定监听套接字
if (bind(listen_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
perror("bind error");
exit(EXIT_FAILURE);
}
// 开始监听
if (listen(listen_fd, MAX_CLIENTS) < 0) {
perror("listen error");
exit(EXIT_FAILURE);
}
// 创建 epoll 实例
if ((epoll_fd = epoll_create(MAX_CLIENTS)) < 0) {
perror("epoll_create error");
exit(EXIT_FAILURE);
}
// 将监听套接字加入 epoll 实例中
event.events = EPOLLIN;
event.data.fd = listen_fd;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_fd, &event) < 0) {
perror("epoll_ctl error");
exit(EXIT_FAILURE);
}
// 循环等待事件
while (true) {
n_ready = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
if (n_ready < 0) {
perror("epoll_wait error");
exit(EXIT_FAILURE);
}
for (int i = 0; i < n_ready; i++) {
if (events[i].data.fd == listen_fd) { // 有新连接
socklen_t cli_len = sizeof(cli_addr);
conn_fd = accept(listen_fd, (struct sockaddr *)&cli_addr, &cli_len);
if (conn_fd < 0) {
perror("accept error");
exit(EXIT_FAILURE);
}
// 将新连接加入 epoll 实例中
event.events = EPOLLIN;
event.data.fd = conn_fd;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, conn_fd, &event) < 0) {
perror("epoll_ctl error");
exit(EXIT_FAILURE);
}
cout << "new client connected: " << inet_ntoa(cli_addr.sin_addr) << endl;
} else { // 有数据可读
conn_fd = events[i].data.fd;
int len = read(conn_fd, buf, BUF_SIZE);
if (len < 0) {
perror("read error");
exit(EXIT_FAILURE);
} else if (len == 0) { // 客户端关闭连接
cout << "client disconnected" << endl;
close(conn_fd);
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, conn_fd, &events[i]);
} else { // 处理客户端发送的消息
buf[len] = '\0';
cout << "recv: " << buf << endl;
write(conn_fd, buf, len);
}
}
}
}
return 0;
}
```
这个示例中,我们创建了一个监听套接字,然后使用 epoll 实例来监听该套接字和所有客户端套接字的事件。当有新客户端连接时,我们将其加入 epoll 实例中,并使用 `read` 函数读取客户端发送的消息;当客户端关闭连接时,我们将其从 epoll 实例中删除。同时,我们使用 `write` 函数向客户端发送消息。
需要注意的是,这个示例仅供参考,具体实现还需要根据自己的需求进行修改和完善。同时,这个示例中没有考虑多线程、多进程等并发情况,如果需要支持更高的并发量,还需要进行相关优化。
相关推荐
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.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)
![](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)