tcp-server-echo epool

直接上代码


#include 
#include 
#include 
#include 
#include 
#include 
 
#include 
#include 
#include 
#include 
#include 
#include 
#include

#define LISTENQ 20  //
#define EPOLLEVENTS 512 // 
#define FDSIZE   1024 //

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

int do_accpet(int epollfd, int listenfd)
{
    int clifd,ret;
    struct sockaddr_in cliaddr;
    socklen_t cliaddrlen=sizeof(struct sockaddr_in);
    struct epoll_event ev;

    clifd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddrlen);
    if (clifd == -1)
    {
        perror("server accpet error");
    }
    else
    {
        ev.events = EPOLLIN|EPOLLERR;
        ev.data.fd = clifd;
        ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, clifd, &ev);
        if(ret != 0 )
        {               
            close(clifd); 
        } 
    }
    return 0;
}

int handle_events(int epollfd, struct epoll_event *events, int num, int listenfd)
{
    int i;
    int fd;
    int ret=0;
    uint8_t buf[4096];
    int len=0,nread=0;
    for (i = 0; i < num; i++)
    {
        fd = events[i].data.fd;
        if ((fd == listenfd) && (events[i].events & EPOLLIN))
        {   
            do_accpet(epollfd, listenfd);     
        }          
        else if (events[i].events & EPOLLIN )
        {
            nread = read(fd, buf, 4096); 
            if(nread > 0)
            {
                write(fd, buf,nread);    
            }
            else 
            {
                epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, NULL);
                close(fd);
            }      
        }
        else if (events[i].events & EPOLLOUT )
        {
           
        }
        else if (events[i].events & EPOLLERR)
        {        
            close(events[i].data.fd);
        }
        else
        {
            
        }       
    }
    return ret;
}

int do_epoll(int listenfd)
{
    int epollfd;
    struct epoll_event events[EPOLLEVENTS];
    int ret;
    struct epoll_event ev;
 
    epollfd = epoll_create(FDSIZE);
    if(epollfd<0)
    {
        exit(1);
    }
    ev.events = EPOLLIN;
    ev.data.fd = listenfd;
    epoll_ctl(epollfd, EPOLL_CTL_ADD, listenfd, &ev);
    for (;;)
    {
        ret = epoll_wait(epollfd, events, EPOLLEVENTS, 1000);
        if(ret < 0)
        {
            perror("epoll_wait error");
            exit(1);
        }
        else if (ret>0)
        {                 
            handle_events(epollfd, events, ret, listenfd);                
        }   
        else
        {
                
           
        }     
    }
    close(epollfd);
}


void mydaemon(void)
{
		int i;
		int fd0;
		pid_t pid;
		struct sigaction sa;
		
		umask(0);
		
		pid = fork();
		if(pid < 0){
				perror("fork error!\n");
				exit(1);
		}else if(pid > 0){
				exit(0);
		}
		
		setsid(); //创建一个会话
		
		sa.sa_handler = SIG_IGN;
		sa.sa_flags = 0;
		sigemptyset(&sa.sa_mask);
		
		if(sigaction(SIGCHLD, &sa, NULL) < 0){//注册子进程退出忽略信号
				return ;
		}
		
		if(chdir("/") < 0){//将当前工作目录更改为根目录
				printf("chlid dir error!\n");
				return;
		}
		
		//关闭不需要的文件描述符,或者重定向到/dev/null
		close(0);
		fd0 = open("/dev/null", O_RDWR);
		dup2(fd0, 1);
		dup2(fd0, 2);
}

int main(int argc, char *argv[])
{
    int listenfd,fd;
    char ip[INET6_ADDRSTRLEN]="127.0.0.1";
    int port = 1234;
    int ret,opt;
    char *optstr = "i:p:";
    while((opt = getopt(argc,argv,optstr))!=-1)
    {
        switch(opt)
        {
            case 'i':
                strcpy(ip,optarg);
                break;
            case 'p':
                port = atoi(optarg);
            break;
            case '?':
                printf("run like: ./echo -i 0.0.0.0  -p 1234\n");
                return 0;
            break;
        }
    }

    mydaemon();

    listenfd = socket_bind(ip, port);
    ret = listen(listenfd, LISTENQ);
    if(ret != 0)
    {
      perror("listen error: ");
      exit(1);  
    }
    printf("listen on %s,%d\n",ip,port);
    do_epoll(listenfd);
    return 0;
}




你可能感兴趣的:(编程语言,tcp/ip)