1. 程式人生 > >Linux----網路程式設計(IO複用之epoll系統呼叫函式)

Linux----網路程式設計(IO複用之epoll系統呼叫函式)

伺服器端epoll.c

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

//ser_epoll
#define MAXFD 10

void epoll_add(int epfd, int fd)
{
    struct epoll_event ev;

// ev.events = EPOLLIN | EPOLLET;
    ev.events = EPOLLIN;
    ev.data.fd = fd;

   if(epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) == -1)
    {
       perror("epoll ctl error");
   }


}

void epoll_del(int epfd, int fd)
{
    if(epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL) == -1)
    {
        perror("epoll ctl del error");
    }
}

int main()
{
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    assert(sockfd != -1);

    struct sockaddr_in saddr, caddr;
    memset(&saddr, 0, sizeof(saddr));
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(6000);
    saddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    int res = bind(sockfd, (struct sockaddr*)&saddr, sizeof(saddr));
    assert(res != -1);

    listen(sockfd, 5);

    int epfd = epoll_create(MAXFD);

    epoll_add(epfd, sockfd);
    struct epoll_event events[MAXFD];

    while( 1 )
    {
        printf("epoll wait\n");
        int n = epoll_wait(epfd, events, MAXFD, 5000);
        if(n == -1)
        {
            printf("epoll_wait error\n");
            continue;
        }
        else if( n == 0 )
        {
            printf("time out\n");
            continue;
        }
        else
        {
            int i = 0;
            for(; i<n; i++)
            {
                int fd = events[i].data.fd;
                if(events[i].events & EPOLLIN)
                {
                    if(fd == sockfd)
                    {
                        int len = sizeof(caddr);
                        int c = accept(sockfd,(struct sockaddr*)&caddr,&len);
                        printf("accept c = %d\n",c);
                       if(c < 0)
                        {
                            continue;
                        }
                        epoll_add(epfd, c);
                    }
                    else
                    {
                            char buff[128] = {0};
                            int num = recv(fd, buff, 127, 0); //將127改為1則變為LT模式
                            if(num <= 0)
                            {
                                epoll_del(epfd, fd);
                                close(fd);
                                printf("one client over\n");
                                break;
                            }
                            printf("recv(%d) = %s\n", fd, buff);
                            send(fd, "ok", 2, 0);
                        }
                    }
                }
            }
        }
    }

客戶端cli_epoll.c

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main()
{
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    assert(sockfd != -1);
    struct sockaddr_in saddr;
    memset(&saddr, 0, sizeof(saddr));
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(6000);
    saddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    int res = connect(sockfd,(struct sockaddr*)&saddr, sizeof(saddr));
    assert(res != -1);

    while(1)
    {
        char buff[128] = {0};
        printf("input:\n");
        fgets(buff,128,stdin);
        if(strncmp(buff,"end",3) == 0)
        {
            break;
            }
        send(sockfd, buff, strlen(buff), 0);
        memset(buff, 0, 128);
        recv(sockfd, buff, 127, 0);
          printf("buff=%s\n",buff);
        }
      close(sockfd);
      exit(0);
    }

執行結果: