Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15317502
  • 博文数量: 2005
  • 博客积分: 11986
  • 博客等级: 上将
  • 技术积分: 22535
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-17 13:56
文章分类

全部博文(2005)

文章存档

2014年(2)

2013年(2)

2012年(16)

2011年(66)

2010年(368)

2009年(743)

2008年(491)

2007年(317)

分类: LINUX

2008-06-10 11:32:31



server.c

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

#define ___PORT 1357
#define ___epoll_parall_events (20)
#define ___epoll_min (10)

static unsigned long ___epoll_max = 1024;
static int sockfd_server;
static int *epollfds;
static int epfd;
static int max_fd = 0;
static struct epoll_event eevents[___epoll_parall_events];

inline void fd_set2(int fd);
inline int fd_get2(int ifd);
inline void fd_clr2(int ifd);
inline void fd_zero2(void);
inline int fd_isset2(int ifd);
inline int fd_isin(int ifd);
void process_data(int sockfd, char *buf);

int main(int argc, char *argv[])
{
    int newsockfd;
    struct sockaddr_in addr;
    int addr_len;
    time_t local_time;
    int readbytes;
    int ret_nums,ifd;
    struct rlimit lim;
    unsigned long user_nums;

    char buffer[256];
    char msg[]="Welcome 2gliethttp server!";

    addr_len = sizeof(struct sockaddr_in);
    if((sockfd_server = socket(PF_INET,SOCK_STREAM,0)) < 0)//申请套接字
    {
        perror("socket");
        return 0;
    }

    memset(&addr, 0, sizeof(addr));
    addr.sin_family =PF_INET;
    addr.sin_port = htons(___PORT);//该套接字对___PORT端口数据进行监听
    addr.sin_addr.s_addr = htonl(INADDR_ANY);//处理来自PC上的任何一块网卡数据

    if(bind(sockfd_server, (struct sockaddr *)&addr, sizeof(addr)) < 0)//将套接字和配置参数绑定在一起
    {
        perror("connect");
        return 0;
    }

    if(listen(sockfd_server, 5) < 0)//同一时刻最多允许5个连接
    {
        perror("listen");
        return 0;
    }

    if(argc > 1) user_nums = strtol(argv[1], 0, 0);
    else user_nums = 0;
    lim.rlim_cur = user_nums + ___epoll_min;
    lim.rlim_max = user_nums + ___epoll_min;
    if(setrlimit(RLIMIT_NOFILE, &lim))
    {
        perror("setrlimit");
        exit(0);
    }
    ___epoll_max = user_nums + ___epoll_min - 1;

    printf("epoll_max=%d\n",___epoll_max);
    fflush(stdout);
    
    epfd = epoll_create(___epoll_max);
    epollfds = malloc(sizeof(int)*___epoll_max);

    fd_zero2();
    fd_set2(sockfd_server);

    max_fd = epfd;
    
    for(;;)
    {
        printf("\nepolling...\n");

        ret_nums = epoll_wait(epfd, eevents, sizeof(eevents)/sizeof(eevents[0]), -1);
        if(ret_nums <= 0)
        {
            perror("epoll error: ");
            exit(-1);
        }
        
        printf("ret_nums=%d\n",ret_nums);
        fflush(stdout);

        for(ifd = 0;ifd < ret_nums;ifd++)
        {
            if(fd_isset2(ifd))
            {
                if(sockfd_server == fd_get2(ifd))
                {
                    //监听端口有连接触发请求了,那么处理之
                    if((newsockfd = accept(sockfd_server,(struct sockaddr *)&addr,(socklen_t*)&addr_len)) < 0)
                      perror("accept");
                    else
                    {
                        if(++max_fd >= ___epoll_max)
                        {
                            max_fd = ___epoll_max;
                            fd_clr2(ifd);
                        }

                        fprintf(stderr,"=====%d=====\n",newsockfd);
                        fd_set2(newsockfd);
                        time(&local_time);
                        sprintf(buffer, "<%d> : %s %s", newsockfd, msg, ctime(&local_time));
                        write(newsockfd, buffer, strlen(buffer));
                        printf("conect: <%d> from %s %s\n", newsockfd, inet_ntoa(addr.sin_addr), ctime(&local_time));
                    }
                }
                else
                {
                    readbytes = read(fd_get2(ifd), buffer, sizeof(buffer));
                    if(readbytes <= 0)
                    {
                        time(&local_time);
                        printf("closed: <%d> %s\n", fd_get2(ifd), ctime(&local_time));
                        fd_clr2(ifd);
                        close(fd_get2(ifd));

                        if(max_fd-- == ___epoll_max)
                        {
                            fd_set2(sockfd_server);
                        }
                    }
                    else
                    {
                        buffer[readbytes] = 0;
                        process_data(fd_get2(ifd), buffer);
                    }
                }
            }
        }
    }
}

inline void fd_set2(int fd)
{
    struct epoll_event eevent;
    eevent.data.fd = fd;
    eevent.events = EPOLLIN;
    if(epoll_ctl(epfd, EPOLL_CTL_ADD, eevent.data.fd, &eevent))
    {
        perror("epoll_ctl(ADD)");
        return;
    }
    int ifd;
    ifd = fd ;//+ 100;
    epollfds[ifd] = fd;
}
inline int fd_get2(int ifd)
{
    return eevents[ifd].data.fd;
}
void fd_remove(int fd)
{
    int i;
    for(i = 0;i < ___epoll_max;i++)
    {
        if(epollfds[i] == fd)
        {
            epollfds[i] = 0;
            break;
        }
    }
}
inline void fd_clr2(int ifd)
{
    struct epoll_event eevent;
    eevent.data.fd = eevents[ifd].data.fd;
    fd_remove(eevent.data.fd);
    if(epoll_ctl(epfd, EPOLL_CTL_DEL, eevent.data.fd, &eevent))
    {
        perror("epoll_ctl(DEL)");
        return;
    }
}
inline void fd_zero2(void)
{
#if 0
    int i;
    for(i = 0;i < ___poll_max;i++)
    {
        pfds[i].fd = 0;
        pfds[i].events = POLLNVAL;
        pfds[i].revents = 0;
    }
#endif
    //memset(pfds, 0, sizeof(pfds));
}
inline int fd_isset2(int ifd)
{
    return 1;
}
inline int fd_isin(int ifd)
{
    return epollfds[ifd];
}

void process_data(int sockfd, char *buf)
{
    char *pdata;
    int idest_sock,dest_sock;
    int tmp_len;
    char buffer[1024*10];
    int ifd;

    if(strncmp("ls", buf, 2) == 0)
    {
        char *p;
        p = buffer;
        for(ifd = 0;ifd < ___epoll_max;ifd++)
        {
            if(fd_isin(ifd))
            {
                if(fd_isin(ifd) == sockfd)p += sprintf(p, "#%d*", ifd);
                p += sprintf(p, "%d\n", fd_isin(ifd));
            }
        }
        write(sockfd, buffer, strlen(buffer));
        return;
    }
    
#if 0
    pdata = strtok(buf, ":");
    if(pdata == NULL)
    {
       
    }
    else
#endif
    {
        pdata = buf;
        dest_sock = strtol(pdata, 0, 0);//atoi(pdata);strtol
        idest_sock = ___epoll_max;
        for(ifd = 0;ifd < ___epoll_max;ifd++)
        {
            if(fd_isin(ifd) == dest_sock)
            {
                idest_sock = ifd;
                break;
            }
        }

        if(idest_sock < ___epoll_max)
        {
                 if(dest_sock < 10)tmp_len = 1;
            else if(dest_sock < 100)tmp_len = 2;
            else if(dest_sock < 1000)tmp_len = 3;
            else tmp_len = 4;
            //pdata = strtok(buf, ":");
            //pdata += strlen(pdata) + 1;
            pdata += tmp_len;

            if(dest_sock == sockfd_server)
            {
                printf("<%d> %s", sockfd, pdata);
                fflush(stdout);
            }
            else
            {
                sprintf(buffer, "<%d> : %s", sockfd, pdata);
                pdata = buffer;
                write(dest_sock, pdata, strlen(pdata));
            }
        }
        else
        {
            sprintf(buffer, "client : %d not exist\n",dest_sock);
            write(sockfd, buffer, strlen(buffer));
        }
    }
}


client.c

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

#define STDIN 0
#define MAXDATASIZE 10240
#define ___epoll_max 2
#define ___epoll_parall_events 4
int main(int argc, char *argv[])
{
    char buf[MAXDATASIZE];
    char send_str[MAXDATASIZE];
    int recvbytes;
    int sockfd,k;
    struct hostent *hp;
    struct sockaddr_in addr;
    char *ip;
    int port;
    int ret_nums,i;
    int epfd;
    struct epoll_event eevents[___epoll_parall_events];

    if(argc < 3)
    {
        printf("client ip port\n");
        return -1;
    }
    ip = argv[1];
    port = atoi(argv[2]);//strtol(argv[2], 0, 0);
    hp = gethostbyname(ip);
    if (hp == NULL)
    {
        perror("hostent error" );
        return -2;
    }

    if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
    {
        perror( "socket error" );
        return( -1 );
    }

    memset(&addr,0,sizeof(struct sockaddr_in));
    addr.sin_family=PF_INET;
    addr.sin_port=htons(port);
    //addr.sin_addr.s_addr=inet_addr(ip);
    memcpy(&addr.sin_addr,hp->h_addr_list[0],hp->h_length);
    //addr.sin_addr.s_addr= htonl(INADDR_ANY);
    printf("Connecting %s:%d ....\n",ip,port);
    fflush(stdout);
    if(connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
    {
        perror("connect");
        exit(1);
    }
    
    epfd = epoll_create(___epoll_max);
    
    eevents[0].events = EPOLLIN;
    eevents[0].data.fd = STDIN;
    epoll_ctl(epfd, EPOLL_CTL_ADD, eevents[0].data.fd, &eevents[0]);

    eevents[0].events = EPOLLIN;
    eevents[0].data.fd = sockfd;
    epoll_ctl(epfd, EPOLL_CTL_ADD, eevents[0].data.fd, &eevents[0]);

    for(;;)
    {
        ret_nums = epoll_wait(epfd, eevents, sizeof(eevents)/sizeof(eevents[0]), -1);
        if(ret_nums <= 0)
        {
            perror("epoll error: ");
            exit(-1);
        }
        
        for(i = 0;i < ret_nums;i++)//如果之允许同时返回1个event,那么这个循环就没用了,因为ret_nums始终为1
        {
            if(eevents[i].data.fd == STDIN)
            {
                fgets(send_str, MAXDATASIZE, stdin);
                send_str[strlen(send_str) - 1] = 0;
                if(strncmp("quit", send_str, 4) == 0)
                {
                    close(sockfd);
                    exit(0);
                }
                send(sockfd, send_str, strlen(send_str), 0);
            }

            if(eevents[i].data.fd == sockfd)
            {
                recvbytes = recv(sockfd, buf, MAXDATASIZE, 0);
                if(recvbytes <= 0)
                {
                    close(sockfd);
                    exit(0);
                }
                buf[recvbytes] = 0;
                printf("-----------\n%s\n", buf);
                fflush(stdout);
            }
        }
    }
}


文件:epoll.tar.gz
大小:2KB
下载:下载

阅读(2228) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~