c_cpp server_tcp_epoll.c

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp server_tcp_epoll.c相关的知识,希望对你有一定的参考价值。

/*================================================
* Author         : Junjie Huang
* Email          : acmhjj@gmail.com
* Last modified  : 2016-02-15 14:38
* Filename       : server_tcp_epoll.c
* Description    : TCP服务端,用epoll实现IO多路复用
================================================*/
#include "func.h"
#define NUM 10

int main (int argc, char const* argv[]){
    if(argc != 3){
        printf("args error\n");
        return -1;
    }
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    if(-1 == sfd){
        perror("socket");
        return -1;
    }
    struct sockaddr_in server_addr;
    bzero(&server_addr, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(argv[1]);
    server_addr.sin_port = htons(atoi(argv[2]));
    int ret = bind(sfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in));
    if(-1 == ret){
        perror("bind");
        close(sfd);
        return -1;
    }
    ret = listen(sfd, NUM);
    if(-1 == ret){
        perror("listen");
        return -1;
    }
    struct sockaddr_in client_addr;
    int length = sizeof(client_addr);
    int newfd = -1;
    char buf[128];
    bzero(buf, sizeof(buf));
    int epfd = epoll_create(1);
    struct epoll_event epev, epevs[3];
    //注册sfd
    epev.events = EPOLLIN;
    epev.data.fd = sfd;
    ret = epoll_ctl(epfd, EPOLL_CTL_ADD, sfd, &epev);
    if(-1 == ret){
        perror("epoll_ctl1");
        return -1;
    }
    //注册STDIN_FILENO
    epev.events = EPOLLIN;
    epev.data.fd = STDIN_FILENO;
    ret = epoll_ctl(epfd, EPOLL_CTL_ADD, STDIN_FILENO, &epev);
    if(-1 == ret){
        perror("epoll_ctl2");
        return -1;
    }
    int i;
    while(1){
        bzero(epevs, sizeof(epevs));
        ret = epoll_wait(epfd, epevs, 3, -1);
        if(ret > 0){
            for(i = 0; i < ret; i++){
                if(epevs[i].data.fd == sfd && epevs[i].events == EPOLLIN){//有新的客户端连接
                    bzero(&client_addr, sizeof(client_addr));
                    newfd = accept(sfd, (struct sockaddr *)&client_addr, &length);
                    if(-1 == newfd){
                        perror("accept");
                        close(sfd);
                        return -1;
                    }
                    epev.events = EPOLLIN;
                    epev.data.fd = newfd;
                    epoll_ctl(epfd, EPOLL_CTL_ADD, newfd, &epev);
                }
                if(newfd > 0){
                    if(epevs[i].data.fd == 0 && epevs[i].events == EPOLLIN){//客户端有发送数据
                        bzero(buf, sizeof(buf));
                        read(0, buf, sizeof(buf));
                        ret = send(newfd, buf, strlen(buf) - 1, 0);
                        if(-1 == ret){
                            perror("send");
                            close(newfd);
                            close(sfd);
                            return -1;
                        }
                    }
                    if(epevs[i].data.fd == newfd && epevs[i].events == EPOLLIN){//标准输入可读
                        bzero(buf, sizeof(buf));
                        ret = recv(newfd, buf, sizeof(buf), 0);
                        if(ret > 0){
                            printf("%s\n", buf);
                        }
                    }
                }
            }
        }
    }
    close(sfd);
    close(epfd);
    return 0;
}

以上是关于c_cpp server_tcp_epoll.c的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp 200.岛屿数量

c_cpp 127.单词阶梯

c_cpp MOFSET

c_cpp MOFSET

c_cpp 31.下一个排列

c_cpp string→char *