客户端 IO复用 多路复用 epoll

#include <netinet/in.h>   
#include <sys/types.h>   
#include <sys/socket.h>   
#include <arpa/inet.h>   
#include <sys/epoll.h>   
#include <errno.h>   
#include <string.h>   
#include <fcntl.h>   
#include <stdlib.h>  
#include <stdio.h>  
#include <string.h>  
#include <unistd.h>  

#define BUFSIZE 512    
#define RET_ERR -1  
#define RET_OK 0  
#define Debug_UserLog printf  
#define Debug_SysLog printf
#define MAX_SOCKET 10000
#define serial_num  10
void SetNonBlock(int fd)   
{   
    int flag = fcntl ( fd, F_GETFL, 0 );   
    fcntl ( fd, F_SETFL, flag | O_NONBLOCK );   
}   

int main(int argc, char** argv)   
{   
    int iRet = RET_OK;   

    if(4 != argc)   
    {   
        Debug_UserLog("Parameter: ServerIP Message ServerPort", RET_ERR);   
        return RET_ERR;   
    }   

    in_port_t i16_port = atoi(argv[3]);   
    if(0 >= i16_port)   
    {   
        Debug_UserLog("port number is wrong", RET_ERR);   
        return RET_ERR;   
    }   

    int sk[MAX_SOCKET];
    for(int i=0;i<serial_num;i++){
        sk[i] = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    }
    if(-1 == sk)   
    {   
        Debug_SysLog("open socket failed!");   
        return RET_ERR;   
    }   


    struct sockaddr_in sa = {0};   
    sa.sin_family = AF_INET;   
    sa.sin_port = htons(i16_port);   

    struct sockaddr_in *psa = &sa;   

    iRet = inet_pton(AF_INET, argv[1], &psa->sin_addr.s_addr);   
    if(0 == iRet)   
    {   
        Debug_UserLog("inet_pton failed, invalid address!", RET_ERR);   
        close(sk);     //有问题没处理 
        return RET_ERR;   
    }   
    else if(iRet < 0)   
    {   
        Debug_SysLog("inet_pton failed");   
        close(sk);    //有问题没处理
        return RET_ERR;   
    }   
    for(int i=0;i<serial_num;i++){
        if(connect(sk[i], (struct sockaddr*)&sa, sizeof(sa)) < 0)   
        {   
            Debug_SysLog("connect failed");   
            close(sk[i]);   //有问题没处理
            return RET_ERR;   
        }   
    }
    for(int i=0;i<serial_num;i++){
        SetNonBlock(sk[i]);   
    }

    int efd;    
    efd = epoll_create(10);    
    if(efd == -1)   
    {   
        perror("epoll_create error!");   
        exit(1);   
    }   

    struct epoll_event event;   
    struct epoll_event events[serial_num];   

    event.events = EPOLLOUT | EPOLLET;   
    for(int i=0;i<serial_num;i++){
        event.data.fd = sk[i];   
        epoll_ctl(efd, EPOLL_CTL_ADD, sk[i], &event);  //加到管理的组
    }


  //  getchar();   
    int loop = 0;   
    while(1)   
    {   
        ssize_t numBytesRcvd = 0;   
        char buffer[BUFSIZE] = {0};   
        int n = 0;   
        int i = 0;   

        if(loop == 1)   
        {   
            break;   
        }   

        n = epoll_wait(efd, events, serial_num, -1);   

        printf("%d\n", n);   

        for(i = 0; i < n; i++)   
        {   
            if(events[i].events & EPOLLOUT)   
            {   
                printf("EPOLLOUT...............\n");   
                //snprintf(buffer, BUFSIZE, "i am process %d, just say: %s\n", getpid(), argv[2]);   

                snprintf(buffer, BUFSIZE,"GET / HTTP/1.1\r\nHOST: www.baidu.com\r\n\r\n" );   

                int n = strlen(buffer);   
                int nsend = 0;   

                while(n > 0)   
                {   
                    //nsend = send(events[i].data.fd, buffer + nsend, n, 0);   
                    nsend = write(events[i].data.fd, buffer + nsend, n);   
                    if(nsend < 0 && errno != EAGAIN)   
                    {   
                        perror("write");

                        Debug_SysLog("send failed");   
                        close(events[i].data.fd);   
                        return RET_ERR;   
                    }   
                    n -= nsend;   
                }   
                event.events = EPOLLIN | EPOLLET; 
                event.data.fd = events[i].data.fd;
                epoll_ctl(efd, EPOLL_CTL_MOD, events[i].data.fd, &event);  //加到管理的组
            }   

            if(events[i].events & EPOLLIN)   
            {   
                printf("EPOLLIN...............\n");   
                memset(buffer, 0, BUFSIZE);   

                int len = strlen(buffer);   
                int n = 0;   
                int nrecv = 0;   


                while(1){   
                    nrecv = read(events[i].data.fd, buffer + n, BUFSIZE - 1) ;   
                    if(nrecv == -1 && errno != EAGAIN)   
                    {   
                        perror("read error!");   
                    }   
                    if((nrecv == -1 && errno == EAGAIN) || nrecv == 0)   
                    {   
                        break;   
                    }   
                    n += nrecv;   
                }   
                //loop = 1;   
                printf("%s\n", buffer);   
            }   
        }   
    }
    for(int i=0;i<serial_num;i++){
        close(sk[i]);
    }
    close(efd);   
    return RET_OK;   
}   

猜你喜欢

转载自blog.csdn.net/qq_23100787/article/details/80231742