Servers poll

Methods poll the server listens on port array used to store them, so that no polling monitor the entire file descriptor

#include <poll.h>
 int poll ( struct the pollfd * FDS, nfds_t NFDs, int timeout);
     struct the pollfd {
         int FD; / * file descriptor * / 
        Short Events; / * monitored event * / 
        Short the revents; / * event monitoring event condition is satisfied returned * / 
    }; 
    priority data POLLIN normal or band-readable, i.e. POLLRDNORM | POLLRDBAND 
    POLLRDNORM-readable data 
    POLLRDBAND priority with data read 
    POLLPRI high priority data readable 
    POLLOUT normal or band data writable  
    POLLWRNORM data can be written
    POLLWRBAND priority band data can be written
    POLLERR error occurred 
    POLLHUP occur pending 
    file descriptor is not a POLLNVAL open 

    nfds monitor how much of the array of file descriptors to be monitored 

    timeout milliseconds to wait
         - 1 : obstruction, #define INFTIM -1 Linux does not define this macro
         0 : return immediately without blocking process
         > 0 : waiting for a specified number of milliseconds, as the current system accuracy is not enough time in milliseconds, ranging up

If you no longer monitor a file descriptor, can pollfd in, fd is set to -1 , poll no longer monitor this pollfd , the next time you return, the revents set to 0 .

 

/* server.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <poll.h>
#include <errno.h>
#include "wrap.h"

#define MAXLINE 80
#define SERV_PORT 6666
#define OPEN_MAX 1024

int main(int argc, char *argv[])
{
    int i, j, maxi, listenfd, connfd, sockfd;
    int nready;
    ssize_t n;
    char buf[MAXLINE], str[INET_ADDRSTRLEN];
    socklen_t clilen;
    struct pollfd client[OPEN_MAX];
    struct sockaddr_in cliaddr, servaddr;

    listenfd = Socket(AF_INET, SOCK_STREAM, 0);

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(SERV_PORT);

    Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

    The Listen (listenfd, 20 is ); 

    Client [ 0 ] = .FD listenfd; 
    Client [ 0 ] = .events POLLRDNORM;                      / * listenfd ordinary read event listener * / 

    for (I = . 1 ; I <the OPEN_MAX; I ++ ) 
        Client [I] .FD = - . 1 ;                              / * -1 for Client initialization [] in the remaining element * / 
    Maxi = 0 ;                                          / * Client [] array element effective maximum element index * / 

    for (;;) { 
        nready = poll ( Client, Maxi + . 1- . 1 );              / * blocking * / 
        IF (Client [ 0 ] .revents & POLLRDNORM) {          / * client connects to the request * / 
            clilen = the sizeof (cliaddr); 
            connfd = the Accept (listenfd, ( struct the sockaddr *) & cliaddr , & clilen); 
            the printf ( " Received from AT PORT% S% D \ n- " , 
                    inet_ntop (AF_INET, & cliaddr.sin_addr, STR, the sizeof (STR)), 
                    ntohs (cliaddr.sin_port)); 
            for (I = . 1; I <the OPEN_MAX; I ++ ) {
                 IF (Client [I] .FD < 0 ) { 
                    Client [I] .FD = connfd;      / * find Client [] in the idle position, storing the returned accept connfd * / 
                    BREAK ; 
                } 
            } 

            IF (I == the OPEN_MAX) 
                perr_exit ( " TOO MANY Clients " ); 

            Client [I] .events = POLLRDNORM;          / * set just returned connfd, monitoring read event * / 
            IF (I> Maxi) 
                Maxi = I;                          / *Update Client [] elements in the standard maximum * / 
            IF (--nready <= 0 )
                 Continue ;                          / * there are no more ready event, continues back to poll blocking * / 
        } 
        for (I = . 1 ; I <= Maxi; ++ I) {              / * detected Client [] * / 
            IF ((Client sockfd = [I] .FD) < 0 )
                 Continue ;
             IF (Client [I] & .revents (POLLRDNORM | POLLERR)) {
                 IF ((n-= the Read (sockfd, buf, MAXLINE)) < 0 ) {
                     IF (errno == ECONNRESET) {/* 当收到 RST标志时 */
                        /* connection reset by client */
                        printf("client[%d] aborted connection\n", i);
                        Close(sockfd);
                        client[i].fd = -1;
                    } else {
                        perr_exit("read error");
                    }
                } else if (n == 0) {
                    /* connection closed by client */
                    printf("client[%d] closed connection\n", i);
                    Close(sockfd);
                    client[i].fd = -1;
                } else {
                    for (j = 0; j < n; j++)
                        buf[j] = toupper(buf[j]);
                        Writen(sockfd, buf, n);
                }
                if (--nready <= 0)
                    break;                 /* no more readable descriptors */
            }
        }
    }
    return 0;
}

client

/* client.c */
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include "wrap.h"

#define MAXLINE 80
#define SERV_PORT 6666

int main(int argc, char *argv[])
{
    struct sockaddr_in servaddr;
    char buf[MAXLINE];
    int sockfd, n;

    sockfd = Socket(AF_INET, SOCK_STREAM, 0);

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
    servaddr.sin_port = htons(SERV_PORT);

    Connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

    while (fgets(buf, MAXLINE, stdin) != NULL) {
        Write(sockfd, buf, strlen(buf));
        n = Read(sockfd, buf, MAXLINE);
        if (n == 0)
            printf("the other side has been closed.\n");
        else
            Write(STDOUT_FILENO, buf, n);
    }
    Close(sockfd);
    return 0;
}

Also contains wrap.c and wrap.h files in the wrong analysis of the blog,

#include <poll.h>

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

    struct pollfd {

        int fd; / * file descriptor * /

        short events; / * monitoring events * /

        short revents; / * monitor events in return to meet the conditions of the event * /

    };

    POLLIN normal or priority band-readable data , i.e. POLLRDNORM | POLLRDBAND       

    POLLRDNORM       data read

    POLLRDBAND       priority band-readable data

    POLLPRI         high priority data is readable

    POLLOUT   normal or band data writable   

    POLLWRNORM       data can be written

    POLLWRBAND       Priority band data can be written

    POLLERR error     

    POLLHUP         hang occurs

    POLLNVAL        descriptor is not an open file

 

    nfds            monitor how much of the array of file descriptors to be monitored

 

    timeout         milliseconds to wait

        -1 : obstruction, #define INFTIM -1                Linux does not define this macro

        0 : return immediately without blocking process

        > 0 : waiting for a specified number of milliseconds, such as the current system time in milliseconds insufficient accuracy, the value upward

 

Guess you like

Origin www.cnblogs.com/wanghao-boke/p/11409506.html