Select servers

select

  1. Select the number of file descriptors can monitor is limited FD_SETSIZE, generally 1024, simply change the number of open file descriptors process does not change the number of select monitor file
  2. 1024 solved using select the following client is very appropriate, but if too many links to the client, select uses a polling model, will greatly reduce the efficiency of server response should not be to invest more in select fine
#include <SYS / SELECT .h>
 / * ACCORDING to Earlier Standards * / 
#include <SYS / time.h> 
#include <SYS / types.h> 
#include <unistd.h>
 int  SELECT ( int NFDs, the fd_set * readfds, fd_set * writefds, 
            fd_set * exceptfds, struct timeval * timeout); 

    NFDs: file descriptor set monitor's maximum file descriptor plus one, because this parameter tells the kernel state how many file descriptors before detection 
    readfds: monitor there are a set of file descriptors to read data arrives, inbound and outbound parameters 
    writefds: monitoring data arrives write file descriptor collection, inbound and outbound parameters 
    exceptfds: monitoring abnormal collection of file descriptors, such as abnormal band data arrives, pass outgoing parameters 
    timeout: Timing blocking monitoring time, three cases 
                1.NULL, wait forever
                 2 provided timeval, waiting for a fixed time.
                 3 disposed in timeval times are 0, returns immediately check descriptor after polling.
     Struct timeval {
         Long the tv_sec; / * seconds The * / 
        Long tv_usec; / * microseconds * / 
    }; 
    void FD_CLR macros ( int fd, the fd_set * sET );      // the file descriptor fd cleared the collection 0 
    int FD_ISSET ( int fd, the fd_set * sET );      // test whether the file descriptor fd is set in the collection. 1 
    void the FD_SET ( int FD, the fd_set * SET );     // the file descriptor fd in the set position 1 
    void FD_ZERO (* fd_set the SET );              // the file descriptor in the set all bits to 0

server

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

#define MAXLINE 80
#define SERV_PORT 6666

int main(int argc, char *argv[])
{
    int i, maxi, maxfd, listenfd, connfd, sockfd;
    int nready, client[FD_SETSIZE];     /* FD_SETSIZE 默认为 1024 */
    ssize_t n;
    fd_set rset, allset;
    char buf[MAXLINE];
    char str[INET_ADDRSTRLEN];             /* #define INET_ADDRSTRLEN 16 */
    socklen_t cliaddr_len;
    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, the sizeof (servaddr)); 

the Listen (listenfd, 20 is );          / * default maximum 128 * / 

maxFd = listenfd;              / * Initialization * / 
Maxi = - . 1 ;                     / * Client [] subscript * / 

for (I = 0 ; I <FD_SETSIZE; I ++ ) 
    Client [I] = - . 1 ;          / * -1 for initialization Client [] * / 

FD_ZERO ( & allset); 
the FD_SET (listenfd, & allset); / * configured to monitor file descriptor select set * / 

for (;;) {
    RSET = allset;              / * all new set select the monitor signal sets each cycle * / 
    nready = select (maxFd + . 1 , & RSET, NULL, NULL, NULL); 

    IF (nready < 0 ) 
        perr_exit ( " select error " );
     IF (FD_ISSET (listenfd, & RSET)) { / * new new Client Connection * / 
        cliaddr_len = the sizeof (cliaddr); 
        connfd = the Accept (listenfd, ( struct the sockaddr *) & cliaddr, & cliaddr_len); 
        the printf ( "% S from AT PORT Received% D \ n- " , 
                inet_ntop (AF_INET, & cliaddr.sin_addr, STR, the sizeof (STR)), 
                ntohs (cliaddr.sin_port)); 
        for (I = 0 ; I <FD_SETSIZE; I ++ ) {
             IF (Client [I] < 0 ) { 
                Client [I] = connfd; / * save file descriptor returned to accept Client [] in * / 
                BREAK ; 
            } 
        } 
        / * reached the maximum number of files to monitor select 1024 * / 
        IF (I == FD_SETSIZE) { 
            fputs ( " TOO MANY Clients \ n-" , Stderr); 
            Exit ( . 1 ); 
        } 

        the FD_SET (connfd, & allset);      / * add a new file descriptor to the monitor signal in the set * / 
        IF (connfd> maxFd) 
            maxFd = connfd;          / * SELECT first parameters needed * / 
        IF (I> Maxi) 
            Maxi = I;                  / * update Client [] max index value * / 

        IF (--nready == 0 )
             Continue ;                  / * If no more file descriptors continue into the ready to select the top blocking monitor,
                                        Ready handles and the unprocessed file descriptor * /
        } 
        For (I = 0 ; I <= Maxi; I ++) {      / * which clients detect data ready * / 
            IF ((sockfd = Client [I]) < 0 )
                 Continue ;
             IF (FD_ISSET (sockfd, & RSET)) {
                 iF ((n-= the Read (sockfd, buf, MAXLINE)) == 0 ) { 
                    the Close (sockfd);         / * when the client closes the link server also closes the corresponding link * / 
                    FD_CLR macros (sockfd, & allset); / * releasing select monitor this file descriptor * / 
                    Client [I] = - . 1 ;
                } else {
                    int j;
                    for (j = 0; j < n; j++)
                        buf[j] = toupper(buf[j]);
                    Write(sockfd, buf, n);
                }
                if (--nready == 0)
                    break;
            }
        }
    }
    close(listenfd);
    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;
}

Contains "wrap.c" and "wrap.h" file on two blog, not repeat it here gives

Guess you like

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