Linux IO多路复用之epoll网络编程
作者:蜗牛201 发布时间:2021-05-07 08:31:19
标签:linux,io多路复用,epoll
前言
本章节是用基本的Linux基本函数加上epoll调用编写一个完整的服务器和客户端例子,可在Linux上运行,客户端和服务端的功能如下:
客户端从标准输入读入一行,发送到服务端
服务端从网络读取一行,然后输出到客户端
客户端收到服务端的响应,输出这一行到标准输出
服务端
代码如下:
#include <unistd.h>
#include <sys/types.h> /* basic system data types */
#include <sys/socket.h> /* basic socket definitions */
#include <netinet/in.h> /* sockaddr_in{} and other Internet defns */
#include <arpa/inet.h> /* inet(3) functions */
#include <sys/epoll.h> /* epoll function */
#include <fcntl.h> /* nonblocking */
#include <sys/resource.h> /*setrlimit */
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#define MAXEPOLLSIZE 10000
#define MAXLINE 10240
int handle(int connfd);
int setnonblocking(int sockfd)
{
if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1) {
return -1;
}
return 0;
}
int main(int argc, char **argv)
{
int servPort = 6888;
int listenq = 1024;
int listenfd, connfd, kdpfd, nfds, n, nread, curfds,acceptCount = 0;
struct sockaddr_in servaddr, cliaddr;
socklen_t socklen = sizeof(struct sockaddr_in);
struct epoll_event ev;
struct epoll_event events[MAXEPOLLSIZE];
struct rlimit rt;
char buf[MAXLINE];
/* 设置每个进程允许打开的最大文件数 */
rt.rlim_max = rt.rlim_cur = MAXEPOLLSIZE;
if (setrlimit(RLIMIT_NOFILE, &rt) == -1)
{
perror("setrlimit error");
return -1;
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl (INADDR_ANY);
servaddr.sin_port = htons (servPort);
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd == -1) {
perror("can't create socket file");
return -1;
}
int opt = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
if (setnonblocking(listenfd) < 0) {
perror("setnonblock error");
}
if (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) == -1)
{
perror("bind error");
return -1;
}
if (listen(listenfd, listenq) == -1)
{
perror("listen error");
return -1;
}
/* 创建 epoll 句柄,把监听 socket 加入到 epoll 集合里 */
kdpfd = epoll_create(MAXEPOLLSIZE);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = listenfd;
if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, listenfd, &ev) < 0)
{
fprintf(stderr, "epoll set insertion error: fd=%d\n", listenfd);
return -1;
}
curfds = 1;
printf("epollserver startup,port %d, max connection is %d, backlog is %d\n", servPort, MAXEPOLLSIZE, listenq);
for (;;) {
/* 等待有事件发生 */
nfds = epoll_wait(kdpfd, events, curfds, -1);
if (nfds == -1)
{
perror("epoll_wait");
continue;
}
/* 处理所有事件 */
for (n = 0; n < nfds; ++n)
{
if (events[n].data.fd == listenfd)
{
connfd = accept(listenfd, (struct sockaddr *)&cliaddr,&socklen);
if (connfd < 0)
{
perror("accept error");
continue;
}
sprintf(buf, "accept form %s:%d\n", inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port);
printf("%d:%s", ++acceptCount, buf);
if (curfds >= MAXEPOLLSIZE) {
fprintf(stderr, "too many connection, more than %d\n", MAXEPOLLSIZE);
close(connfd);
continue;
}
if (setnonblocking(connfd) < 0) {
perror("setnonblocking error");
}
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = connfd;
if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, connfd, &ev) < 0)
{
fprintf(stderr, "add socket '%d' to epoll failed: %s\n", connfd, strerror(errno));
return -1;
}
curfds++;
continue;
}
// 处理客户端请求
if (handle(events[n].data.fd) < 0) {
epoll_ctl(kdpfd, EPOLL_CTL_DEL, events[n].data.fd,&ev);
curfds--;
}
}
}
close(listenfd);
return 0;
}
int handle(int connfd) {
int nread;
char buf[MAXLINE];
nread = read(connfd, buf, MAXLINE);//读取客户端socket流
if (nread == 0) {
printf("client close the connection\n");
close(connfd);
return -1;
}
if (nread < 0) {
perror("read error");
close(connfd);
return -1;
}
write(connfd, buf, nread);//响应客户端
return 0;
}
编译
编译和启动服务端
gcc epollserver.c -o epollserver
./epollserver
来源:https://blog.csdn.net/woniu211111/article/details/47318843


猜你喜欢
- 在一个著名博客上的评论一天可能被几百个读者浏览。随着博客寿命的延长,读者会越多,您会发现一个简单的评论会映射您自己。每个博客评论通常都是永久
- 内容摘要:最近不少朋友及客户的服务器遇到arp欺骗攻击,造成站点被挂木马.由于是采用ARP技术欺骗,所以主机并没入侵,在服务器里查看网页源码
- 有的Godaddy主机用户反映,不能生成HTML?针对Godaddy WINDOWS 主机生成HTML问题如下:第一、生成HTML用的是FS
- 自从2004年芙蓉姐姐横空出世,神话到处流传至今无人超越,又谣传芙蓉姐姐去韩国整容之后美貌值暴涨。小编好奇之下用美图秀秀图片处理软件,借用芙
- 北京时间5月13日消息,据国外媒体报道,雅虎日前宣布将允许外部网站使用雅虎的地理信息数据库,并允许开发者在应用程序中加入雅虎的数据和服务。雅
- 最新消息,康盛创想(Comsenz)旗下核心产品UCenter Home(简称UCHome)当前应用站点已经超过15万家。UCenter H
- 瑞士数据保护专员星期五宣布,他将在有关于谷歌“街景”设施引起隐私担心的纠纷中把谷歌告上法庭。瑞士联邦
- 中国的站长比中国的牛还多;吹牛的站长比喝啤酒吹酒瓶的人要多,不会吧?看到某篇文章这么写的。个人做站,很多人为了兴趣,业余做站,交流思想技术交
- 以前在windows下面做过web服务器,但是还从来没有在linux下做过。今天,终于下定了决心,试着做一个,顺便学点知知识。在window
- 我从www.xrnic.cn开通了一个独立IP LINUX空间,空间支持伪静态功能。由于网站根目录下安装的是DEDECMS,bbs目录下安装
- RedHat Linux 为增加系统安全性提供了防火墙保护。防火墙存在于你的计算机和网络之间,用来判定网络中的远程用户有权访问你的计算机上的
- 不写前言,不讲废话,大家直接看例子.用实例说话,看了后自己去思考.好好思考.1:我没有去查baiducom.com是不是已经被注册,我也没去
- 在一台服务器的使用上,磁盘往往占据着很重要的位置。服务器磁盘的配置和维护对整个服务器性能方面产生很大影响。实际上,优化服务器磁盘的方法只需要
- 实践证明,基于Windows NT 的Exchange Server并不是企业级电子邮件系统的最佳选择。由于对稳定性等性能要求非常高,因此大
- 一个文档标题,最好的定义方法是什么?要回答这个问题,先设想我们要在一个页面上定义文章的标题,通常我们有三个方法来实现这个简单目的:方法一:
- 在这个阴郁的天这个阴郁的房间,我的心情也阴郁的一塌糊涂,请原谅我的矫情,因为我的内心像是一片不能宁静的沙漠海,说它是海是因为它曾经给我过激情
- 什么是Linux中的路由和路由表?路由的过程意味着IP包在网络上从一点传输到另一点。当你向某人发送电子邮件时,你实际上是在将一系列IP数据包
- 11月20日下午消息,搜狐IT今日从播放软件暴风影音内部获悉,该公司在10月份首次实现盈亏平衡,当月收入突破1000万元。内部员工透露,暴风
- 由于需要在mac环境下做些开发,手头没有苹果机器,所以决定先整个虚拟机环境来试试。自己整理了一下过程.当中有参考其它资料。友情提示:可能比较
- 微信小程序 Linux开发环境微信小程序开发工具是用nw.js实现的,这玩意本来就可以跨平台的。搞不懂为什么微信只出了windows和mac