Function prototype
# Include <poll. h>
Int poll (struct pollfd FDS [], nfds_t NFDs, int timeout );
Typedef struct pollfd {
Int FD;/* file descriptor to be detected or selected */
Short events;/* events of interest to the file descriptor FD */
Short revents;/* events actually occurred on the file descriptor FD */
} Pollfd_t;
Typedef unsigned long nfds_t;
Parameter description:
FDS: an array of the struct pollfd structure to store the socket descriptor that needs to detect its status. The system does not clear the array after calling this function, which is convenient to operate; especially when many socket connections exist, the processing efficiency can be improved to some extent. This is different from the select () function. After the select () function is called, select () the function clears the socket descriptor set it detects, so that the socket descriptor must be added to the set to be checked before each select () call. Therefore, select () the function is suitable for detecting only one socket descriptor, while the poll () function is suitable for detecting a large number of socket descriptors;
NFDs: nfds_t type parameter, used to mark the total number of struct elements in the array FDS;
Timeout: the time when the poll function call is blocked. Unit: milliseconds;
Return Value:
> 0: Total number of socket descriptors in the array FDS with read, write, or error statuses ready;
= 0: no socket descriptor in the array FDS is ready for read, write, or error. In this case, Poll times out and the timeout time is timeout millisecond. In other words, if no event occurs on the detected socket descriptor, the poll () function blocks the specified length of milliseconds for timeout and returns the result. If timeout = 0, then poll () the function returns immediately without blocking. If timeout = inftim, the poll () function will continue to block until the event of interest on the detected socket descriptor is returned, if an event of interest never occurs, Poll () will be blocked forever;
-1: the poll function fails to be called, and the global variable errno is automatically set;
Special instructions
If the socket descriptor to be detected is a negative value, the detection of this descriptor will be ignored, that is, the member variable events will not be detected, events registered on events are also ignored. When the poll () function returns, the member variable revents is set to 0, indicating that no event has occurred;
In addition, the poll () function will not be affected and restricted by the o_ndelay mark and o_nonblock mark on the socket descriptor, that is, whether the socket is blocked or not blocked, Poll () the Select () function is different. The select () function is affected by the o_ndelay mark and o_nonblock mark. If the socket is a blocked socket, select () is called () the effect is the same as that when select () is not called. The socket is still blocked TCP communication. On the contrary, if the socket is not blocked, select () is called () non-blocking TCP communication can be implemented;
Therefore, the function and return value of the poll () function have the same meaning as the function and return value of the select () function. The difference between the two is that the internal implementation method is different. Select () functions can basically run on all system platforms that support file descriptor operations (such as Linux, UNIX, windows, and MACOs), with good portability, while poll () functions are supported only by some operating systems (such as SunOS, Solaris, Aix, and HP, but not Linux), with poor portability;
Code example (reproduced) Server
# 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 <stdlib. h> # include <errno. h> # include <stdio. h> # include <string. h> # include <poll. h>/* poll function */# include <limits. h> # define maxline 10240 # ifndef open_max # define open_max 40960 # endifvoid handle (struct pollfd * clients, int maxclient, int readyclient); int main (INT argc, char ** argv) {int servport = 6888; int listenq = 1024; int listenfd, connfd; struct pollfd clients [open_max]; int Maxi; socklen_t socklen = sizeof (struct sockaddr_in); struct sockaddr_in cliaddr, servaddr; char Buf [maxline]; int nready; bzero (& servaddr, socklen); servaddr. sin_family = af_inet; servaddr. sin_addr.s_addr = htonl (inaddr_any); servaddr. sin_port = htons (servport); listenfd = socket (af_inet, sock_stream, 0); If (listenfd <0) {perror ("socket error");} int opt = 1; if (setsockopt (listenfd, sol_socket, so_reuseaddr, & OPT, sizeof (OPT) <0) {perror ("setsockopt error");} If (BIND (listenfd, (struct sockaddr *) & servaddr, socklen) =-1) {perror ("BIND error"); exit (-1);} If (Listen (listenfd, listenq) <0) {perror ("Listen error");} clients [0]. FD = listenfd; Clients [0]. events = Pollin; int I; for (I = 1; I <open_max; I ++) clients [I]. FD =-1; Maxi = listenfd + 1; printf ("pollechoserver startup, listen on port: % d \ n", servport ); printf ("Max connection is % d \ n", open_max); For (;) {nready = poll (clients, Maxi + 1,-1 ); // printf ("nready is % d \ n", nready); If (nready =-1) {perror ("poll error ");} if (clients [0]. revents & Pollin) {connfd = accept (listenfd, (struct sockaddr *) & cliaddr, & socklen); sprintf (BUF, "accept Form % s: % d \ n ", inet_ntoa (cliaddr. sin_addr), cliaddr. sin_port); printf (BUF, ""); for (I = 0; I <open_max; I ++) {If (clients [I]. FD =-1) {clients [I]. FD = connfd; Clients [I]. events = Pollin; break; }}if (I = open_max) {fprintf (stderr, "too connected connection, more than % d \ n", open_max ); close (connfd); continue;} if (I> Maxi) maxi = I; -- nready;} Handle (clients, Maxi, nready );}} void handle (struct pollfd * clients, int maxclient, int nready) {int connfd; int I, nread; char Buf [maxline]; If (nready = 0) return; for (I = 1; I <maxclient; I ++) {connfd = clients [I]. FD; If (connfd =-1) continue; If (clients [I]. revents & (Pollin | pollerr) {nread = read (connfd, Buf, maxline); // read client socket stream if (nread <0) {perror ("read error"); close (connfd); Clients [I]. FD =-1; continue;} If (nread = 0) {printf ("client close the connection"); close (connfd); Clients [I]. FD =-1; continue;} write (connfd, Buf, nread); // response client if (-- nready <= 0) // No connection needs to be processed, exit loop break ;}}}
Client
# 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 <netdb. h>/* gethostbyname function */# include <stdlib. h> # include <errno. h> # include <stdio. h> # include <string. h> # define maxline 1024 void handle (INT connfd); 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: echoclient <IPaddress> <port> \ n "); Return-1 ;}connfd = socket (af_inet, sock_stream, 0); bzero (& servaddr, sizeof (servaddr )); servaddr. sin_family = af_inet; servaddr. sin_port = htons (servport); inet_ton (af_inet, servinetaddr, & servaddr. sin_addr); If (connect (connfd, (struct sockaddr *) & servaddr, sizeof (servaddr) <0) {perror ("Connect error"); Return-1 ;} printf ("Welcome to echoclient \ n"); handle (connfd);/* do it all */close (connfd); printf ("Exit \ n "); exit (0);} void handle (INT sockfd) {char sendline [maxline], recvline [maxline]; int N; For (;) {If (fgets (sendline, maxline, stdin) = NULL) {break; // read EOF}/* // You can also skip the buffer stream of the standard library, directly use the system function without caching to operate if (read (stdin_fileno, sendline, maxline) = 0) {break; // read EOF} */N = write (sockfd, sendline, strlen (sendline); n = read (sockfd, recvline, maxline); If (n = 0) {printf ("echoclient: Server terminated prematurely \ n "); break;} write (stdout_fileno, recvline, n); // If the cached stream output from the standard library is used, problems may occur sometimes. // fputs (recvline, stdout );}}