网络编程之epoll模型,亲测可用

1 篇文章 0 订阅
1 篇文章 0 订阅

服务端代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <unistd.h>
#include <sys/types.h>

#define IPADDRESS “127.0.0.1”
#define PORT 8787
#define MAXSIZE 1024
#define LISTENQ 5
#define FDSIZE 1000
#define EPOLLEVENTS 100

//函数声明
//创建套接字并进行绑定
static int socket_bind(const char *ip,int port);

//I/O多路复用epoll
static void do_epoll(int listenfd);

//事件处理函数
static void handle_events(int epollfd,struct epoll_event *events,int num,int listenfd,char *buf);

//处理接收到的连接
static void handle_accpet(int epollfd,int listenfd);

//读取处理
static void do_read(int epollfd,int fd,char *buf);

//写入处理
static void do_write(int epollfd,int fd,char *buf);

//添加事件
static void add_event(int epollfd,int fd,int state);

//修改事件
static void modify_event(int epollfd,int fd,int state);

//删除事件
static void delete_event(int epollfd,int fd,int state);

int main(int argc,char *argv[])
{
int listenfd;
listenfd = socket_bind(IPADDRESS,PORT);
listen (listenfd,LISTENQ);
do_epoll(listenfd);
return 0;
}

static int socket_bind(const char * ip,int port)
{
int listenfd;
struct sockaddr_in serveraddr;
listenfd = socket(AF_INET,SOCK_STREAM,0);
if( listenfd== -1 ){
perror(“create socket error”);
exit(1);
}
bzero(&serveraddr,sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
inet_pton(AF_INET,ip,&serveraddr.sin_addr);
serveraddr.sin_port = htons(port);
if(bind(listenfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr)) == -1 ){
perror(“bind error”);
exit(1);
}
return listenfd;
}

static void do_epoll(int listenfd)
{
int epollfd;
struct epoll_event events[EPOLLEVENTS];
int ret;
char buf[MAXSIZE]="";
memset(buf,0,MAXSIZE);
//创建描述符
epollfd = epoll_create(FDSIZE);
//添加监听描述符事件
add_event(epollfd,listenfd,EPOLLIN);
for( ; ; )
{
ret = epoll_wait(epollfd,events,EPOLLEVENTS,-1);
handle_events(epollfd,events,ret,listenfd,buf);
}
close(epollfd);
}

static void handle_events(int epollfd,struct epoll_event * events,int num,int listenfd,char * buf)
{
int i;
int fd;
//遍历
for( i=0;i<num;i++ ){
fd = events[i].data.fd;
//根据描述符类型和事件类型处理
if((fd==listenfd) && (events[i].events &EPOLLIN))
handle_accpet(epollfd,listenfd);
else if( events[i].events &EPOLLIN )
do_read(epollfd,fd,buf);
else if( events[i].events &EPOLLOUT )
do_write(epollfd,fd,buf);
}
}

static void handle_accpet(int epollfd,int listenfd)
{
int clientfd;
struct sockaddr_in clientaddr;
socklen_t clientaddrlen;
clientfd = accept(listenfd,(struct sockaddr*)&clientaddr,&clientaddrlen);
if( clientfd == -1 ){
perror(“accept error”);
}else{
printf(“accept a new client: %s:%d\n”,inet_ntoa(clientaddr.sin_addr),clientaddr.sin_port);
//添加一个客户描述符和事件
add_event(epollfd,clientfd,EPOLLIN);
}
}

static void do_read(int epollfd,int fd,char * buf)
{
int nread;
nread = read(fd,buf,MAXSIZE);
if( nread == -1 ){
perror(“read error”);
close(fd);
delete_event(epollfd,fd,EPOLLIN);
}else if( nread == 0 ){
fprintf(stderr,“client close\n”);
close(fd);
delete_event(epollfd,fd,EPOLLIN);
}else{
printf(“read msg is %s”,buf);
//修改描述符对应的事件,由读改为写
modify_event(epollfd,fd,EPOLLOUT);
}
}

static void do_write(int epollfd,int fd,char * buf)
{
int nwrite;
nwrite = write(fd,buf,strlen(buf));
if( nwrite == -1 ){
perror(“write error”);
close(fd);
delete_event(epollfd,fd,EPOLLOUT);
}else{
modify_event(epollfd,fd,EPOLLOUT);
}
memset(buf,0,MAXSIZE);
}

static void add_event(int epollfd,int fd,int state)
{
struct epoll_event ev;
ev.events = state;
ev.data.fd = fd;
epoll_ctl(epollfd,EPOLL_CTL_ADD,fd,&ev);
}

static void modify_event(int epollfd,int fd,int state)
{
struct epoll_event ev;
ev.events = state;
ev.data.fd = fd;
epoll_ctl(epollfd,EPOLL_CTL_MOD,fd,&ev);
}

static void delete_event(int epollfd,int fd,int state)
{
struct epoll_event ev;
ev.events = state;
ev.data.fd = fd;
epoll_ctl(epollfd,EPOLL_CTL_DEL,fd,&ev);
}

/*
 sockaddr_in结构体:

struct sockaddr_in {
short int sin_family; // Address family
unsigned short int sin_port; // Port number
struct in_addr sin_addr; // Internet address
unsigned char sin_zero[8]; // Same size as struct sockaddr
};
  
  sockaddr结构体:

struct sockaddr {
unsigned short sa_family; // address family, AF_xxx
char sa_data[14]; // 14 bytes of protocol address
};
  
  in_addr结构体:

struct in_addr {
unsigned long s_addr; // that’s a 32-bit long, or 4 bytes
};
*/
客户端代码:
#include <netinet/in.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
#include <arpa/inet.h>

#define MAXSIZE 1024
#define IPADDRESS “127.0.0.1”
#define SERV_PORT 8787
#define FDSIZE 1024
#define EPOLLEVENTS 20

//函数声明
static void handle_connection(int sockfd);
static void handle_events(int epollfd,struct epoll_event * events,int num,int sockfd,char * buf);
static void do_read(int epollfd,int fd,int sockfd,char * buf);
static void do_write(int epollfd,int fd,int socked,char * buf);
static void add_event(int epollfd,int fd,int state);
static void modify_event(int epollfd,int fd,int state);
static void delete_event(int epollfd,int fd,int state);

int main(int argc,char *argv[])
{
int sockfd;
struct sockaddr_in serveraddr;
sockfd = socket(AF_INET,SOCK_STREAM,0);
bzero(&serveraddr,sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(SERV_PORT);
inet_pton(AF_INET,IPADDRESS,&serveraddr.sin_addr);
connect(sockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));
//处理连接
handle_connection(sockfd);
close(sockfd);
return 0;
}

static void handle_connection(int sockfd)
{
int epollfd;
struct epoll_event events[EPOLLEVENTS];
char buf[MAXSIZE]="";
int ret;
epollfd = epoll_create(FDSIZE);
add_event(epollfd,STDIN_FILENO,EPOLLIN);
for( ; ; )
{
ret = epoll_wait(epollfd,events,EPOLLEVENTS,-1);
handle_events(epollfd,events,ret,sockfd,buf);
}
close(epollfd);
}

static void handle_events(int epollfd,struct epoll_event * events,int num,int sockfd,char * buf)
{
int fd,i;
for( i=0;i<num;i++ ){
fd = events[i].data.fd;
if(events[i].events & EPOLLIN)
do_read(epollfd,fd,sockfd,buf);
else if(events[i].events &EPOLLOUT)
do_write(epollfd,fd,sockfd,buf);
}
}

static void do_read(int epollfd,int fd,int sockfd,char * buf)
{
int nread;
nread = read(fd,buf,MAXSIZE);
if( nread == -1 ){
perror(“read error”);
close(fd);
}else if( nread ==0 ){
fprintf(stderr,“server closed\n”);
close(fd);
}else{
if( fd == STDIN_FILENO )
add_event(epollfd,fd,EPOLLOUT);
else{
delete_event(epollfd,fd,EPOLLIN);
add_event(epollfd,STDOUT_FILENO,EPOLLOUT);
}
}
}

static void do_write(int epollfd,int fd,int sockfd,char * buf)
{
int nwrite;
nwrite = write(fd,buf,strlen(buf));
if( nwrite == -1 ){
perror(“write error”);
close(fd);
}else{
if( fd== STDOUT_FILENO )
delete_event(epollfd,fd,EPOLLOUT);
else
modify_event(epollfd,fd,EPOLLIN);
}
memset(buf,0,MAXSIZE);
}

static void add_event(int epollfd,int fd,int state)
{
struct epoll_event ev;
ev.events = state;
ev.data.fd = fd;
epoll_ctl(epollfd,EPOLL_CTL_ADD,fd,&ev);
}

static void modify_event(int epollfd,int fd,int state)
{
struct epoll_event ev;
ev.events = state;
ev.data.fd = fd;
epoll_ctl(epollfd,EPOLL_CTL_MOD,fd,&ev);
}

static void delete_event(int epollfd,int fd,int state)
{
struct epoll_event ev;
ev.events = state;
ev.data.fd = fd;
epoll_ctl(epollfd,EPOLL_CTL_DEL,fd,&ev);
}

服务端代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <unistd.h>
#include <sys/types.h>

#define IPADDRESS “127.0.0.1”
#define PORT 8787
#define MAXSIZE 1024
#define LISTENQ 5
#define FDSIZE 1000
#define EPOLLEVENTS 100

//函数声明
//创建套接字并进行绑定
static int socket_bind(const char *ip,int port);

//I/O多路复用epoll
static void do_epoll(int listenfd);

//事件处理函数
static void handle_events(int epollfd,struct epoll_event *events,int num,int listenfd,char *buf);

//处理接收到的连接
static void handle_accpet(int epollfd,int listenfd);

//读取处理
static void do_read(int epollfd,int fd,char *buf);

//写入处理
static void do_write(int epollfd,int fd,char *buf);

//添加事件
static void add_event(int epollfd,int fd,int state);

//修改事件
static void modify_event(int epollfd,int fd,int state);

//删除事件
static void delete_event(int epollfd,int fd,int state);

int main(int argc,char *argv[])
{
int listenfd;
listenfd = socket_bind(IPADDRESS,PORT);
listen (listenfd,LISTENQ);
do_epoll(listenfd);
return 0;
}

static int socket_bind(const char * ip,int port)
{
int listenfd;
struct sockaddr_in serveraddr;
listenfd = socket(AF_INET,SOCK_STREAM,0);
if( listenfd== -1 ){
perror(“create socket error”);
exit(1);
}
bzero(&serveraddr,sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
inet_pton(AF_INET,ip,&serveraddr.sin_addr);
serveraddr.sin_port = htons(port);
if(bind(listenfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr)) == -1 ){
perror(“bind error”);
exit(1);
}
return listenfd;
}

static void do_epoll(int listenfd)
{
int epollfd;
struct epoll_event events[EPOLLEVENTS];
int ret;
char buf[MAXSIZE]="";
memset(buf,0,MAXSIZE);
//创建描述符
epollfd = epoll_create(FDSIZE);
//添加监听描述符事件
add_event(epollfd,listenfd,EPOLLIN);
for( ; ; )
{
ret = epoll_wait(epollfd,events,EPOLLEVENTS,-1);
handle_events(epollfd,events,ret,listenfd,buf);
}
close(epollfd);
}

static void handle_events(int epollfd,struct epoll_event * events,int num,int listenfd,char * buf)
{
int i;
int fd;
//遍历
for( i=0;i<num;i++ ){
fd = events[i].data.fd;
//根据描述符类型和事件类型处理
if((fd==listenfd) && (events[i].events &EPOLLIN))
handle_accpet(epollfd,listenfd);
else if( events[i].events &EPOLLIN )
do_read(epollfd,fd,buf);
else if( events[i].events &EPOLLOUT )
do_write(epollfd,fd,buf);
}
}

static void handle_accpet(int epollfd,int listenfd)
{
int clientfd;
struct sockaddr_in clientaddr;
socklen_t clientaddrlen;
clientfd = accept(listenfd,(struct sockaddr*)&clientaddr,&clientaddrlen);
if( clientfd == -1 ){
perror(“accept error”);
}else{
printf(“accept a new client: %s:%d\n”,inet_ntoa(clientaddr.sin_addr),clientaddr.sin_port);
//添加一个客户描述符和事件
add_event(epollfd,clientfd,EPOLLIN);
}
}

static void do_read(int epollfd,int fd,char * buf)
{
int nread;
nread = read(fd,buf,MAXSIZE);
if( nread == -1 ){
perror(“read error”);
close(fd);
delete_event(epollfd,fd,EPOLLIN);
}else if( nread == 0 ){
fprintf(stderr,“client close\n”);
close(fd);
delete_event(epollfd,fd,EPOLLIN);
}else{
printf(“read msg is %s”,buf);
//修改描述符对应的事件,由读改为写
modify_event(epollfd,fd,EPOLLOUT);
}
}

static void do_write(int epollfd,int fd,char * buf)
{
int nwrite;
nwrite = write(fd,buf,strlen(buf));
if( nwrite == -1 ){
perror(“write error”);
close(fd);
delete_event(epollfd,fd,EPOLLOUT);
}else{
modify_event(epollfd,fd,EPOLLOUT);
}
memset(buf,0,MAXSIZE);
}

static void add_event(int epollfd,int fd,int state)
{
struct epoll_event ev;
ev.events = state;
ev.data.fd = fd;
epoll_ctl(epollfd,EPOLL_CTL_ADD,fd,&ev);
}

static void modify_event(int epollfd,int fd,int state)
{
struct epoll_event ev;
ev.events = state;
ev.data.fd = fd;
epoll_ctl(epollfd,EPOLL_CTL_MOD,fd,&ev);
}

static void delete_event(int epollfd,int fd,int state)
{
struct epoll_event ev;
ev.events = state;
ev.data.fd = fd;
epoll_ctl(epollfd,EPOLL_CTL_DEL,fd,&ev);
}

/*
 sockaddr_in结构体:

struct sockaddr_in {
short int sin_family; // Address family
unsigned short int sin_port; // Port number
struct in_addr sin_addr; // Internet address
unsigned char sin_zero[8]; // Same size as struct sockaddr
};
  
  sockaddr结构体:

struct sockaddr {
unsigned short sa_family; // address family, AF_xxx
char sa_data[14]; // 14 bytes of protocol address
};
  
  in_addr结构体:

struct in_addr {
unsigned long s_addr; // that’s a 32-bit long, or 4 bytes
};
*/

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值