zoukankan      html  css  js  c++  java
  • linux C poll 函数使用

    在学习linux 并发非阻塞服务器时候。看到有使用poll 函数的方式。初步理解并编写程序进行了测试。

    服务器:

    #include  <unistd.h>
    #include  <sys/types.h>       /* basic system data types */
    #include  <sys/socket.h>      /* basic socket definitions */
    #include  <netinet/in.h>      /* sockaddr_in{} and other Internet defns */
    #include  <arpa/inet.h>       /* inet(3) functions */
    #include  <poll.h>
    
    #include <stdlib.h>
    #include <errno.h>
    #include <stdio.h>
    #include <string.h>
    
    #define MAX_LINK 10
    
    int main()
    {
        struct sockaddr_in server_addr,client_addr;
        bzero(&server_addr, sizeof(server_addr));
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        server_addr.sin_port = htons(6888);
        
        socklen_t socklen = sizeof(struct sockaddr_in);
        
        int ser_fd,con_fd;
        ser_fd=socket(AF_INET, SOCK_STREAM, 0);
    
        if(bind(ser_fd, (struct sockaddr*)&server_addr, sizeof(struct sockaddr_in)) == -1) {
            perror("bind error");
            exit(-1);
        }
    
        if (listen(ser_fd,10) < 0) {
            perror("listen error");
            return -1;
        }
        
        struct pollfd fds[MAX_LINK];
        fds[0].fd=ser_fd;
        fds[0].events=POLLRDNORM;
        int i=1;
        for(;i<MAX_LINK;i++){
            fds[i].fd=-1;
            fds[i].events=POLLRDNORM;    
        }
        
        int ready_n;
        
        int link_count=1;
        
        char buffer[1024];
        
        while(1){
            ready_n=poll(fds,link_count,-1);
            if(ready_n==-1){
                printf("poll error 
    ");
                return 0;
            }
            if(fds[0].revents & POLLRDNORM){
                int cli=accept(ser_fd, (struct sockaddr*) &client_addr, &socklen);
                for(i=1;i<MAX_LINK;i++){
                    if(fds[i].fd<0){
                        fds[i].fd=cli;
                        printf("new connect : %d 	",i);
                        printf("%d
    ",link_count);
                        break;
                    }
                }
                link_count++;
                ready_n--;
            }
            for(i=1;i<MAX_LINK && ready_n>0;i++){
                if(fds[i].fd >0){
                    if(fds[i].revents & POLLRDNORM){
                        int n=recv(fds[i].fd,buffer,1024,0);
                        if(n==0){
                            fds[i].fd=-1;
                            link_count--;
                            
                        }else if(n>0){
                            send(fds[i].fd,buffer,n,0);
                        }
                        ready_n--;
                    }
                }
            
            }
                
        
        }
        
    
        return 0;
    }

    客户端:

    #include  <unistd.h>
    #include  <sys/types.h>       /* basic system data types */
    #include  <sys/socket.h>      /* basic socket definitions */
    #include  <netinet/in.h>      /* sockaddr_in{} and other Internet defns */
    #include  <arpa/inet.h>       /* inet(3) functions */
    #include <sys/select.h>       /* select function*/
    
    #include <stdlib.h>
    #include <errno.h>
    #include <stdio.h>
    #include <string.h>
    
    #define MAXLINE 10240
    #define max(a,b)    ((a) > (b) ? (a) : (b))
    //typedef struct sockaddr  SA;
    
    void handle(int sockfd);
    
    int main(int argc, char **argv)
    {
        char * servInetAddr = "127.0.0.1";
        int servPort = 6888;
        char buf[MAXLINE];
        int connfd;
        struct sockaddr_in servaddr;
        
        if (argc == 2) {
            servInetAddr = argv[1];
        }
        if (argc == 3) {
            servInetAddr = argv[1];
            servPort = atoi(argv[2]);
        }
        if (argc > 3) {
            printf("usage: selectechoclient <IPaddress> <Port>
    ");
            return -1;
        }
    
        connfd = socket(AF_INET, SOCK_STREAM, 0);
    
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(servPort);
        inet_pton(AF_INET, servInetAddr, &servaddr.sin_addr);
        
        if (connect(connfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) {
            perror("connect error");
            return -1;
        }
        printf("welcome to selectechoclient
    ");
        handle(connfd);     /* do it all */
        close(connfd);
        printf("exit
    ");
        exit(0);
    }
    
    
    void handle(int connfd)
    {
        FILE* fp = stdin;
        char sendline[MAXLINE], recvline[MAXLINE];
        fd_set rset;
        FD_ZERO(&rset);
        int maxfds = max(fileno(fp), connfd) + 1;
        int nread;
        for (;;) {
            FD_SET(fileno(fp), &rset);
            FD_SET(connfd, &rset);
    
            if (select(maxfds, &rset, NULL, NULL, NULL) == -1) {
                perror("select error");
                continue;
            }
    
            if (FD_ISSET(connfd, &rset)) {
                //接收到服务器响应
                nread = read(connfd, recvline, MAXLINE);
                if (nread == 0) {
                    printf("server close the connection
    ");
                    break;
                } 
                else if (nread == -1) {
                    perror("read error");
                    break;    
                }
                else {
                    //server response
                    write(STDOUT_FILENO, recvline, nread);    
                }  
            }
    
            if (FD_ISSET(fileno(fp), &rset)) {
                //标准输入可读
                if (fgets(sendline, MAXLINE, fp) == NULL) {
                    //eof exit
                    break;   
                } 
                else {
                    write(connfd, sendline, strlen(sendline));  
                }
            }
    
        } 
    }
  • 相关阅读:
    wss的webpart的3种开发方式(转载)
    C# 2.0学习之集合2
    对C#中的TreeView添加背景图转载
    ASP.NET 2.0: 页面中链入的CSS、js文件带中文时需注意
    C# 2.0学习之泛型
    C# 2.0学习之数组
    连接 ACCESS 2007
    C# 2.0学习之事件2
    一个P2P+搜索音乐网站的策划书(转载)
    关于MOSS的应用和开发的一些联接
  • 原文地址:https://www.cnblogs.com/justboy/p/6703965.html
Copyright © 2011-2022 走看看