Detail Select function (C language)

Source: Internet
Author: User
Tags readable

Select in the socket programming is still more important, but for beginners socket people are not too fond of using Select to write programs, they are just used to writing such as Connect, accept, Blocking programs such as recv or recvfrom (the so-called blocking mode block, as the name suggests, is that processes or threads must wait for an event to occur when the function is executed, and if the event does not occur, the process or thread is blocked and the function cannot return immediately). But using a select allows you to do non-blocking (the so-called non-blocking Non-block, where a process or thread performs this function without having to wait for the event to occur, once the execution returns, to reflect the difference in the value of the function, and if the event occurs the same way as blocking, If the event does not occur, return a code to tell the event not to occur, and the process or thread continues to execute, so the more efficient way to work the program, it can monitor the change of the file descriptor we need to monitor-read-write or abnormal.

function format for select:

int select (int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval*timeout);

Two structures are described first:

First, struct fd_set can be understood as a set, which holds a file descriptor (FileDescriptor), which is a file handle, which can be the common meaning of what we call a file, of course, any device, pipeline, FIFO, etc. are file forms, all included, so there is no doubt that a socket is a file, the socket handle is a file descriptor. The Fd_set collection can be manipulated by some macros, such as emptying the collection Fd_zero (Fd_set *), adding a given file descriptor to the collection fd_set (int, fd_set*), removing a given file descriptor from the collection fd_clr (int, fd_set*), checks whether the specified file descriptor in the collection can read and write Fd_isset (int, fd_set*).

second, struct timevalis a commonly used structure that represents the time value, has two members, one is the number of seconds, the other is the number of milliseconds.

to explain the parameters of a select specifically:
int MAXFDP is an integer value that refers to the range of all file descriptors in the collection, that is, the maximum value of all file descriptors plus 1, not wrong. The value of this parameter in Windows does not matter and can be set incorrectly.

Fd_set * Readfds is a pointer to the FD_SET structure, which should include a file descriptor that we want to monitor for read changes to these file descriptors, that is, we care about whether we can read data from these files, if there is a file in the collection that is readable, The select returns a value greater than 0, indicating that a file is readable, and if there are no readable files, then the timeout is judged according to the timeout parameter, and if the time exceeds timeout, select returns 0, which returns a negative value if an error occurs. You can pass in a null value to indicate that you do not care about read changes to any file.

Fd_set * Writefds is a pointer to the FD_SET structure, which should include file descriptors, and we want to monitor the write changes of these file descriptors, that is, we care about whether we can write data to these files, if there is a file in the collection that can be written, Select returns a value greater than 0, indicating that there is a file to write, if there is no writable file, then the timeout parameter to determine whether to timeout, if more than timeout time, select return 0, if an error returns a negative value. You can pass in a null value, indicating that you don't care about any file's write changes.

Fd_set * Errorfds with the above two parameters to monitor file error exceptions.

struct Timeval * Timeout is the timeout for select, which is critical in that it allows the select to be in three states, first, if NULL is passed in as a formal parameter, without passing in the time structure, the select is placed in a blocking state, Be sure to wait until a file descriptor in the collection of the monitor file descriptor changes; second, if the time value is set to 0 seconds 0 milliseconds, it becomes a pure non-blocking function, regardless of whether the file descriptor changes, immediately return to continue execution, the file does not change the return of 0, there are changes to return a positive; third, The value of the timeout is greater than 0, which is the timeout for the wait, that is, the select is blocked in the timeout time and the event comes back within the timeout period, otherwise it will be returned after the timeout, and the return value is the same as above.

return Value: Returns the total number of descriptors in which the state has changed.
Negative value: Select Error

Positive values: Some files can be read or written or error

0: Wait timeout, no read-write or wrong file

Select Example:

① reads the keyboard input value, timeout interval 2.5 seconds, output the number of characters entered by the user.

#include <sys/types.h> #include <sys/time.h> #include <stdio.h> #include <fcntl.h> #include <sys/ioctl.h> #include <unistd.h> int main () {char buffer[128]; int result, nread; fd_set inputs, Testfds; St Ruct timeval timeout; Fd_zero (&inputs)////////////////////////////////////////////(0) while (1) {Testfds = inputs; timeout.tv_sec = 2; timeout.tv_usec = 500000: result = Select (Fd_setsize, &testfds, fd_s ET *) 0, (Fd_set *) 0, &timeout); Switch (Result) {case 0:printf ("timeout/n"), break; Case-1: Perror ("select"); exit (1); Default:if (Fd_isset FDS)) {IOCTL (0,fionread,&nread);//Gets the number of characters entered from the keyboard, including carriage returns. if (nread = = 0) {printf ("keyboard done/n"); exit (0);} nread = Read (0,buffer,nread); Buffer[nread] = 0; printf ("Read%d from keyboard:%s", nread, buffer); } break; } return 0; }

② uses select instead of fork to solve multiple customer problems in the socket.

Server side:

#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> # Include <sys/time.h> #include <sys/ioctl.h> #include <unistd.h> int main () {int SERVER_SOCKFD, Client_ SOCKFD; int Server_len, Client_len; struct sockaddr_in server_address; struct sockaddr_in client_address; int result; Fd_set Readfds, Testfds; SERVER_SOCKFD = socket (af_inet, sock_stream, 0);//Set up server-side socket server_address.sin_family = af_inet; SERVER_ADDRESS.SIN_ADDR.S_ADDR = htonl (Inaddr_any); Server_address.sin_port = htons (9734); Server_len = sizeof (server_address); Bind (SERVER_SOCKFD, (struct sockaddr *) &server_address, Server_len); Listen (SERVER_SOCKFD, 5); Fd_zero (&readfds); Fd_set (SERVER_SOCKFD, &readfds);//Add server-side sockets to the collection while (1) {char ch; int fd; int nread; Testfds = Readfds; printf (" Server waiting/n "); /* Indefinite blocking, and test file descriptor changes * * result = Select (Fd_setsize, &testfds, (Fd_set *) 0, (Fd_set *) 0, (struct Timeval *) 0); if (Result < 1) {perror ("Server5"); exit (1);/* Scan all file descriptors */for (fd = 0; fd < fd_setsize; fd++) {/* Find the relevant file descriptor/if (Fd_isset Testfds)) {/* Determines whether it is a server socket and is a request for a connection from the customer. */if (FD = = server_sockfd) {Client_len = sizeof (client_address); client_sockfd = Accept (SERVER_SOCKFD, struct sockaddr * ) &client_address, &client_len); Fd_set (CLIENT_SOCKFD, &readfds);//Adds the client socket to the collection printf ("Adding Client on FD%d/n", CLIENT_SOCKFD); }/* Client socket with data request/else {IOCTL (FD, Fionread, &nread);//Get Data amount to nread/* Customer Data request complete, close socket, clear the corresponding descriptor from the collection/if (Nread = 0) {close (FD); FD_CLR (FD, &readfds); printf ("Removing Client on FD%d/n", FD); /* Processing customer data request/else {read (FD, &ch, 1); sleep (5); printf ("Serving Client on FD%d/n", FD); ch++; write (FD, &ch, 1) ; } } } } } }

Client:

#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> # Include <arpa/inet.h> #include <unistd.h> int main () {int client_sockfd; int len; struct sockaddr_in address; Server-side network address structure body int result; char ch = ' A '; CLIENT_SOCKFD = socket (af_inet, sock_stream, 0);//Establish client socket address.sin_family = af_inet; ADDRESS.SIN_ADDR.S_ADDR = inet_addr ("127.0.0.1"); Address.sin_port = 9734; Len = sizeof (address); result = Connect (CLIENT_SOCKFD, (struct sockaddr *) &address, Len); if (result = = 1) {perror ("Oops:client2"); exit (1);} write (CLIENT_SOCKFD, &ch, 1); Read (CLIENT_SOCKFD, &ch, 1); printf ("char from server =%c/n", ch); Close (CLIENT_SOCKFD); Zexit (0); }

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.