Linux Network Programming step by step-select details

Source: Internet
Author: User

The Select system call enables our program to monitor the State Changes of multiple file handles (file descriptor. The program stops at select and waits until one or more of the monitored file handles change their status. There are many file handles in Linux. If you use a man function, when the return value of the function is complete, a file handle is created, for example, man socket can see "on success, a file descriptor for the new socket is returned. "Man 2 open can see" open () and creat () return the new file descriptor ". In fact, the file handle is an integer. You can see the socket function declaration:

Int socket (INT domain, int type, int Protocol );

Of course, the most familiar handles are 0, 1, and 2. 0 indicates the standard input, 1 indicates the standard output, and 2 indicates the standard error output. 0, 1, and 2 are integers. The corresponding file * structure is represented by stdin, stdout, stderr, 0 is stdin, 1 is stdout, and 2 is stderr. For example, the following two sections of Code read 9 bytes from the standard input:

# Include <stdio. h>

# Include <unistd. h>

# Include <string. h>

Int main (INT argc, char ** argv)

{

Char Buf [10] = "";

Read (0, Buf, 9);/* read characters from the standard input 0 */

Fprintf (stdout, "% s/n", Buf);/* output stdout write characters to the standard */

Return 0;

}

/*** The code above and below can be used to read the 9 characters entered by the user from the standard input ***/

# Include <stdio. h>

# Include <unistd. h>

# Include <string. h>

Int main (INT argc, char ** argv)

{

Char Buf [10] = "";

Fread (BUF, 9, 1, stdin);/* read characters from the standard input stdin */

Write (1, Buf, strlen (BUF ));

 

Return 0;

}

The preceding SELECT statement is used to monitor the status changes of one or more handles.

The prototype of the select function is as follows:

Int select (INT NFDs, fd_set * readfds, fd_set * writefds, fd_set * limit TFDs, struct timeval * timeout );

The last timeout parameter of the function is obviously a timeout value. Its type is struct timeval *, which is a pointer to a variable in the struct timeval structure, so we need to declare a struct timeval TV in the program; then pass the TV variable address & TV to the select function. The structure of struct timeval is as follows:

Struct timeval

{

Long TV _sec;/* seconds */

Long TV _usec;/* microseconds */

};

The three parameters 2nd, 3, and 4 are of the same type: fd_set *, that is, we need to declare several fd_set variables in the program, such as rdfds, wtfds, exfds, then, pass the address & rdfds, & wtfds, & exfds of the variable to the select function.

These three parameters are a collection of handles. The first rdfds is used to save such a handle: When the handle status changes to readable, the system will tell the select function to return, similarly, the second wtfds indicates that the system will tell the select function to return a result when the handle state is changed to writable. Similarly, the third parameter exfds is a special case, that is, the system will tell the select function to return when the handle is generated in special cases. In special cases, for example, the other Party sends emergency data through a socket handle. If we only want to check whether data in a socket is readable, we can:

Fd_set rdfds;/* declare an fd_set set to save the socket handle to be detected */

Struct timeval TV;/* declare a time variable to save the time */

Int ret;/* Save the returned value */

Fd_zero (& rdfds);/* clears the set before using the select function */

Fd_set (socket, & rdfds);/* Add the socket of the handle to be detected to the Set */

 

TV. TV _sec = 1;

TV. TV _usec = 500;/* set the maximum waiting time for select to 1 second plus 500 microseconds */

 

Ret = select (socket + 1, & rdfds, null, null, & TV);/* checks whether the handle set in rdfds has readable information */

If (Ret <0)

Perror ("select");/* This indicates that the select function has an error */

Else if (ret = 0)

Printf ("time-out/N");/* indicates that the status of the socket has not changed within the time range of 1 second plus 500 milliseconds */

Else

{/* Indicates that the waiting time is less than 1 second plus 500 milliseconds, and the socket status has changed */

Printf ("ret = % d/N", RET);/* The returned value of RET records the number of State-changing handles. Since we only monitor the socket handle, therefore, RET must be 1. If multiple handles change at the same time, the total number of handles is returned */

/* Here we should read data from the socket handle, because the select function has told us that the handle contains data readable */

If (fd_isset (socket, & rdfds) {/* first checks whether the handle monitored outside the socket is actually readable */

/* Read data in the socket handle */

Recv (...);

}

}

Note that the first parameter of the select function is the maximum value of all the handle values that are added to the set. For example, we have created three handles:

 

Int SA, Sb, SC;

Sa = socket (...);/* create three handles respectively and connect them to the server */

Connect (SA ,...);

SB = socket (...);

Connect (SB ,...);

SC = socket (...);

Connect (SC ,...);

Fd_set (SA, & rdfds);/* add three handles to the read monitoring set respectively */

Fd_set (SB, & rdfds );

Fd_set (SC, & rdfds );

Before using the select function, you must find the maximum value among the three handles. We generally define a variable to save the maximum value and obtain the maximum socket value as follows:

Int maxfd = 0;

If (Sa> maxfd)

Maxfd = sa;

If (Sb> maxfd)

Maxfd = Sb;

If (SC> maxfd)

Maxfd = SC;

Then, call the select function:

Ret = select (maxfd + 1, & rdfds, null, null, & TV);/* Add 1 to the maximum value */

In the same way, if we want to check whether the user enters the input by the keyboard, we should put the handle of the standard input 0 in the SELECT statement to check, as shown below:

Fd_zero (& rdfds );

Fd_set (0, & rdfds );

TV. TV _sec = 1;

TV. TV _usec = 0;

Ret = select (1, & rdfds, null, null, & TV);/* Note that the maximum value must be 1 */

If (Ret <0)

Perror ("select");/* Error */

Else if (ret = 0)

Printf ("timeout/N");/* the user does not press the keyboard during the specified time TV */

Else {/* the user has a keyboard to read the user's input */

Scanf ("% s", Buf );}

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.