Epoll 的tcp通信代码(服务器+客户端)

来源:互联网 发布:windows ce系统升级 编辑:程序博客网 时间:2024/05/02 17:49

Epoll 的tcp通信代码(服务器+客户端)

/*gcc -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I${ORACLE_HOME}/rdbms/public -I${ORACLE_HOME}/rdbms/demo -L${ORACLE_HOME}/lib -lclntsh  -pthread -o epoll_server epoll_server.c*/#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h>#include <sys/wait.h>#include <unistd.h>#include <arpa/inet.h>#include <fcntl.h>#include <sys/epoll.h>#include <sys/time.h>#include <sys/resource.h>#define MAXBUF 1024#define MAXEPOLLSIZE 10000/*setnonblocking - 设置句柄为非阻塞方式*/int setnonblocking(int sockfd){    if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1) {        return -1;    }    return 0;}/*handle_message - 处理每个 socket 上的消息收发*/int handle_message(int new_fd){    char buf[MAXBUF + 1];    char sendbuf[MAXBUF+1];    int len;    /* 开始处理每个新连接上的数据收发 */    bzero(buf, MAXBUF + 1);    /* 接收客户端的消息 */    len = recv(new_fd, buf, MAXBUF, 0);    if (len > 0){        printf("%d接收消息成功:'%s',共%d个字节的数据/n",new_fd, buf, len);    }    else {        if (len < 0)            printf("消息接收失败!错误代码是%d,错误信息是'%s'/n",errno, strerror(errno));        else            printf("客户端%d退出!/n",new_fd);        return -1;    }    /* 处理每个新连接上的数据收发结束 */    return len;}int main(int argc, char **argv){    int listener, new_fd, nfds, n, ret;    struct epoll_event ev;    int kdpfd, curfds;    socklen_t len;    struct sockaddr_in my_addr, their_addr;    unsigned int myport, lisnum;    struct epoll_event events[MAXEPOLLSIZE];    struct rlimit rt;    if (argc>1)    myport = atoi(argv[1]);    else    myport = 1234;    if (argc>2)    lisnum = atoi(argv[2]);    else    lisnum = 10;    /* 设置每个进程允许打开的最大文件数 */    rt.rlim_max = rt.rlim_cur = MAXEPOLLSIZE;    if (setrlimit(RLIMIT_NOFILE, &rt) == -1) {        perror("setrlimit");        exit(1);    }    else printf("设置系统资源参数成功!/n");    /* 开启 socket 监听 */    if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) {        perror("socket");        exit(1);    } else    printf("socket 创建成功!/n");    /*设置socket属性,端口可以重用*/    int opt=SO_REUSEADDR;    setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));    /*设置socket为非阻塞模式*/    setnonblocking(listener);    bzero(&my_addr, sizeof(my_addr));    my_addr.sin_family = PF_INET;    my_addr.sin_port = htons(myport);    if (argc>3)    my_addr.sin_addr.s_addr = inet_addr(argv[3]);    else    my_addr.sin_addr.s_addr = INADDR_ANY;    if (bind(listener, (struct sockaddr *) &my_addr, sizeof(struct sockaddr))== -1) {        perror("bind");        exit(1);    }     else        printf("IP 地址和端口绑定成功/n");    if (listen(listener, lisnum) == -1) {        perror("listen");        exit(1);    } else    printf("开启服务成功!/n");    /* 创建 epoll 句柄,把监听 socket 加入到 epoll 集合里 */    kdpfd = epoll_create(MAXEPOLLSIZE);    len = sizeof(struct sockaddr_in);    ev.events = EPOLLIN | EPOLLET;    ev.data.fd = listener;    if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, listener, &ev) < 0) {        fprintf(stderr, "epoll set insertion error: fd=%d/n", listener);        return -1;    }     else    printf("监听 socket 加入 epoll 成功!/n");    curfds = 1;    while (1) {        /* 等待有事件发生 */        nfds = epoll_wait(kdpfd, events, curfds, -1);        if (nfds == -1) {            perror("epoll_wait");            break;        }        /* 处理所有事件 */        for (n = 0; n < nfds; ++n) {            if (events[n].data.fd == listener) {                new_fd = accept(listener, (struct sockaddr *) &their_addr,                &len);                if (new_fd < 0) {                    perror("accept");                    continue;                else                printf("有连接来自于:%s:%d,分配的 socke为:%d/n",inet_ntoa(their_addr.sin_addr), ntohs(their_addr.sin_port), new_fd);                setnonblocking(new_fd);                ev.events = EPOLLIN | EPOLLET;                ev.data.fd = new_fd;                if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, new_fd, &ev) < 0) {                    fprintf(stderr, "把 socket '%d' 加入 epoll 失败!%s/n",                    new_fd, strerror(errno));                    return -1;                }                curfds++;            } else {                ret = handle_message(events[n].data.fd);                if (ret < 1 && errno != 11) {                    if(epoll_ctl(kdpfd, EPOLL_CTL_DEL, events[n].data.fd,                                &ev) < 0)                    {                        fprintf(stderr, "把 socket '%d' 从 epoll 删除失败!%s/n",                        events[n].data.fd, strerror(errno));                    }                    curfds--;                    close(events[n].data.fd);                }            }        }    }    close(listener);    return 0;}
tcp客户端client.c:#include <sys/types.h>#include <sys/socket.h>#include <stdio.h>#include <unistd.h>#include <netinet/in.h>#include <arpa/inet.h>#include <errno.h>#include <sys/select.h>#include <stdlib.h>#include <string.h>#include <fcntl.h>#define MAXLINE 1024char sendhead[MAXLINE];int main(int argc , char* argv[]){    int sockfd;    struct sockaddr_in servaddr;    char *info="cxt";    int   maxfdp1, stdineof;    fd_set  rset;    char  recvbuf[MAXLINE],tmp[128],sendbuf[MAXLINE];    int   n,len,fd;    if(argc!=3){        printf("useage:client address port ");        exit(0);    }    if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1  )    {        perror("socket");        exit(1);    }    printf("%s connect server/n",info);    bzero(&servaddr,sizeof(servaddr));    servaddr.sin_family=AF_INET;    servaddr.sin_port=htons(atoi(argv[2]));    inet_pton(AF_INET,argv[1],&servaddr.sin_addr);    if( ( connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr))  )<0)    {        perror("connect");        exit(1);    }    send(sockfd,info,strlen(info),0);    for ( ; ; ) {        FD_ZERO(&rset);        FD_SET(sockfd, &rset);        FD_SET(0, &rset);         maxfdp1=sockfd+1;        if((select(maxfdp1, &rset, NULL, NULL, NULL) )<=0){            perror("select");        }else{            if (FD_ISSET(0,&rset)){                fgets(sendbuf, MAXLINE, stdin);                n=send(sockfd,sendbuf,strlen(sendbuf)-1,0);                if(n>0)                printf("send: %s",sendbuf);                else                printf("send: %s error,the erro cause is %s:%s/n",sendbuf,errno,strerror(errno));                bzero(sendbuf,strlen(sendbuf));            }            if (FD_ISSET(sockfd, &rset)) { /* socket is readable */                n=recv(sockfd, recvbuf, MAXLINE,0) ;                if(n<0) {                    perror("str_cli: server terminated prematurely");                }else if(n==0)                {                    printf("sever shutdown!");                    exit(-1);                }                //recvbuf                recvbuf[n]='/0';                printf("receive :%s/n",recvbuf);                fflush(stdout);                bzero(recvbuf,strlen(recvbuf));            }        }    }    exit(0);}
1 0
原创粉丝点击