直接贴代码,代码是运行在Linux上面的,通过 g++ epoll.cpp
编译
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#define MAX_CONN 1024
#define BUF_SIZE 1024
int main()
{
int serv_fd;
char buf[BUF_SIZE];
sockaddr_in serv_addr,cli_addr;
int eph;
socklen_t lt;
struct epoll_event ev,events[MAX_CONN];
serv_fd = socket(AF_INET,SOCK_STREAM,0);
eph = epoll_create(MAX_CONN); // 创建 epoll 句柄
if (eph < 0)
{
perror("创建epoll错误");
return -1;
}
// 把对监听套接字serv_fd的可读事件加入到监听列表
ev.events = EPOLLIN|EPOLLET;
ev.data.fd = serv_fd;
epoll_ctl(eph,EPOLL_CTL_ADD,serv_fd,&ev);
bzero(&serv_addr, sizeof(serv_addr)); // 类似于 memset() 清空一块内存
inet_aton("0.0.0.0",&(serv_addr.sin_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(7007); // 不能使用 htonl函数,执行不会 出错,但是也不会监听
if(bind(serv_fd,(sockaddr*)&serv_addr,sizeof(serv_addr)) < 0)
{
perror("绑定错误");
return -1;
}
listen(serv_fd,50);
for(;;)
{
// 这里会阻塞,但是第三个参数指定500ms之后超时返回
// 没有事件发生,返回0
int n = epoll_wait(eph,events,MAX_CONN,500);
for(int i=0;i<n;i++)
{
if(events[i].data.fd == serv_fd) // 如果是用于监听的套接字有事件发生,那就是有新连接到达了
{
int cli_fd = accept(serv_fd,(sockaddr*)&cli_addr,<); // 接收连接
if(cli_fd<0){perror("连接建立错误");continue;}
printf("来自 %s 的连接\n",inet_ntoa(cli_addr.sin_addr));
// 以下三行用于将新连接的套接字添加到监听列表
ev.data.fd = cli_fd;
ev.events = EPOLLIN | EPOLLET; // 设置监听这个套接字的可读事件,并且指定是 ET 模式
epoll_ctl(eph,EPOLL_CTL_ADD,cli_fd,&ev);
}else if(events[i].events & EPOLLIN) // 发现套接字可读
{
int fd = events[i].data.fd;
int n = read(fd,buf,BUF_SIZE);
if(n < 0) // 接收失败,将套接字移除监听列表
{ // 断开连接
ev.events = EPOLLIN;
ev.data.fd = fd;
epoll_ctl(eph,EPOLL_CTL_DEL,fd,&ev);
printf("断开连接\n");
continue;
}
buf[n] = '\0';
printf("接收数据: %s\n",buf);
write(fd,buf,n); // 直接写入 发回
}
else if(events[i].events & EPOLLOUT)
{// 要注意的是,上面调用write不会触发下面这个事件, 只有满了的缓冲区重新空闲的时候会触发 https://www.zhihu.com/question/22840801
printf("EPOLLOUT\n");
// int fd = events[i].data.fd;
// write(fd,buf,BUF_SIZE);
}
}
}
return 0;
}
之后客户端使用 netcat 代替
执行命令 nc 127.0.0.1 7007
就能连接上服务端,无论发什么都会发回来
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/225565.html