📄 server_epoll.c
字号:
/*********************************************************
author: Adam Huang
date:2005-10-26
*********************************************************/
#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 <signal.h>
typedef unsigned int UINT32;
#include "packet.h"
#define MAX_FDS 20480
#define MAX_EVENTS 20480
#define LISTENQ 4096
#define SERV_PORT 5555
#define INFTIM 1000
/////////////////Used for report traffic
UINT32 total_bytes =0;
UINT32 total_packets =0;
UINT32 in_bytes = 0;
UINT32 in_packets = 0;
UINT32 out_bytes = 0;
UINT32 out_packets = 0;
UINT32 moment_conns = 0;
int report_interval = 5;
UINT32 times = 1;
void traffic_report(int none)
{
fprintf(stderr,"%-10d %-12d %-13d %-15d %-10d %-12d %-11d %d\n",
report_interval * times,
moment_conns,
total_bytes/report_interval,
total_packets/report_interval,
in_bytes/report_interval,
in_packets/report_interval,
out_bytes/report_interval,
out_packets/report_interval);
total_bytes = 0;
total_packets = 0;
in_bytes = 0;
in_packets = 0;
out_bytes = 0;
out_packets = 0;
times ++;
if(moment_conns < 0)
moment_conns = 0;
signal(SIGALRM,traffic_report);
alarm(report_interval);
}
void setnonblocking(int sock)
{
int opts;
opts=fcntl(sock,F_GETFL);
if(opts<0)
{
perror("fcntl(sock,GETFL)");
exit(1);
}
opts = opts|O_NONBLOCK;
if(fcntl(sock,F_SETFL,opts)<0)
{
perror("fcntl(sock,SETFL,opts)");
exit(1);
}
}
int main(int argc,char ** argv)
{
int i, maxi, listenfd, connfd, sockfd,epfd,nfds;
ssize_t n;
char line[MAXLINE];
socklen_t clilen;
//声明epoll_event结构体的变量,ev用于注册事件,数组用于回传要处理的事件
struct epoll_event ev,events[MAX_EVENTS];
if(argc != 3){
printf("usage:%s [port] [report_interval]\n",argv[0]);
exit(-1);
}
report_interval = atoi(argv[2]);
if(report_interval <= 0)
report_interval = 5;
system("echo \"Testting Start time:\"`date +%y-%m-%d/%H:%M:%S`");
fprintf(stderr,"Port:%d\n",atoi(argv[1]));
fprintf(stderr,"Report interval:%ds\n",report_interval);
signal(SIGALRM,traffic_report);
alarm(report_interval);
fprintf(stderr,"%-10s %-10s %-10s %-10s %-10s %-10s %-10s %s\n",
"xthScends",
"moment_conns",
"total_bytes/s",
"total_packets/s",
"in_bytes/s",
"in_packets/s",
"out_bytes/s",
"out_packets/s");
//生成用于处理accept的epoll专用的文件描述符
epfd=epoll_create(MAX_FDS);
struct sockaddr_in clientaddr;
struct sockaddr_in serveraddr;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
//把socket设置为非阻塞方式
setnonblocking(listenfd);
//设置与要处理的事件相关的文件描述符
ev.data.fd=listenfd;
//设置要处理的事件类型
ev.events=EPOLLIN|EPOLLET;
//注册epoll事件
epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev);
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htons(INADDR_ANY);
//serveraddr.sin_port=htons(SERV_PORT);
serveraddr.sin_port=htons(atoi(argv[1]));
bind(listenfd,(struct sockaddr *)&serveraddr, sizeof(serveraddr));
listen(listenfd, LISTENQ);
maxi = 0;
for ( ; ; ) {
//等待epoll事件的发生
nfds=epoll_wait(epfd,events,MAX_EVENTS,-1);
//处理所发生的所有事件
for(i=0;i<nfds;++i)
{
memset(line,'\0',sizeof(line));
if(events[i].data.fd==listenfd)
{
connfd = accept(listenfd,(struct sockaddr *)&clientaddr, &clilen);
if(connfd<0){
perror("connfd<0");
continue;
//exit(1);
}
setnonblocking(connfd);
moment_conns ++ ;
char *str = inet_ntoa(clientaddr.sin_addr);
//printf("connect from %s;fd:%d\n",str,connfd);
//设置用于读操作的文件描述符
ev.data.fd=connfd;
//设置用于注测的读操作事件
ev.events=EPOLLIN|EPOLLET;
//注册ev
epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev);
}
else if(events[i].events&EPOLLIN)
{
if ( (sockfd = events[i].data.fd) < 0){
moment_conns -- ;
continue;
}
if ( (n = read(sockfd, line, REQUEST_LEN)) <= 0) {
moment_conns -- ;
//if (errno == ECONNRESET) {
close(sockfd);
events[i].data.fd = -1;
//}
continue;
}
total_bytes = total_bytes + n;
total_packets ++;
in_bytes = in_bytes + n;
in_packets ++;
//printf("read %d bytes form sockfd :%d\n",n,sockfd);
//设置用于写操作的文件描述符
ev.data.fd=sockfd;
//设置用于注测的写操作事件
ev.events=EPOLLOUT|EPOLLET;
//修改sockfd上要处理的事件为EPOLLOUT
epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);
}
else if(events[i].events&EPOLLOUT)
{
sockfd = events[i].data.fd;
if ( sockfd < 0){
moment_conns -- ;
continue;
}
memset(line, '\0', sizeof(line));
memset(line, 'A' , RESPONSE_LEN);
n = write (sockfd, line, RESPONSE_LEN);
if (n <= 0){
moment_conns -- ;
close(sockfd);
events[i].data.fd = -1;
continue;
}
total_bytes = total_bytes + n;
total_packets ++ ;
out_bytes = out_bytes + n;
out_packets ++ ;
//printf("write %d bytes to fd %d \n",n , sockfd);
//设置用于读操作的文件描述符
ev.data.fd=sockfd;
//设置用于注测的读操作事件
ev.events=EPOLLIN|EPOLLET;
//修改sockfd上要处理的事件为EPOLIN
epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);
}
else{
printf("Unknown error! event.data.fd:%d\n",events[i].data.fd);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -