Select is still important in socket programming, but it is not very popular for beginners of socket programming,
They are just used to writing blocking programs such as connect, accept, Recv, or recvfrom,
As the name suggests, a process or thread must wait for an event to occur when executing these functions. If the event does not occur, the process
Or the thread is blocked, and the function cannot return immediately ). However, you can use select to complete non-blocking (non-block in the so-called non-blocking mode,
That is, when a process or thread executes this function, it does not have to wait for the event to occur. Once the execution is successful, the return value is different to reflect the function's
Execution status. If the event occurs in the same way as the blocking mode, if the event does not occur, a code is returned to inform the event that it has not occurred, and the process or
Threads continue to execute, so it is more efficient) The program that works in a way that can monitor changes in the file descriptor we need to monitor-read/write or exceptions.
The following describes in detail:
Select Function Format (I am talking about Berkeley socket programming in UNIX, which is different from that in windows. I will explain it later ):
Int select (INT maxfdp, fd_set * readfds, fd_set * writefds, fd_set * errorfds, struct timeval * timeout );
Two struct types are described first:
1: struct fd_set can be understood as a collection in which the file descriptor (filedescriptor) is stored, that is, the file handle,
This can be what we call a common file. Of course, any device, pipeline, and FIFO in UNIX are all in the file format, so
There is no doubt that a socket is a file,The socket handle is a file descriptor..
The fd_set set can be operated manually by some macros, such as clearing the fd_zero (fd_set *) set a given file descriptor.
Add fd_set (INT, fd_set *) to the Set; Delete fd_clr (INT, fd_set *) from the set for a given file descriptor; check
Set whether the specified file descriptor can read and write fd_isset (INT, fd_set *). For example.
Second, struct timeval is a common structure used to represent the time value. It has two members: one is the number of seconds and the other is the number of milliseconds.
Specific interpretation of select parameters:
Int maxfdp is an integer that indicates the range of all file descriptors in the collection. That is, the maximum value of all file descriptors is 1. It cannot be wrong!
In Windows, the value of this parameter does not matter. You can set it incorrectly.
Fd_set * readfds is a pointer to the fd_set structure. This collection should contain file descriptors. We want to monitor the read changes of these file descriptors,
That is, we are concerned about whether data can be read from these files. If a file in this collection is readable, select returns a value greater than 0, indicating that the file is readable,
If there is no readable file, the timeout parameter is used to determine whether to time out. If the time exceeds the timeout time, select returns 0. If an error occurs, a negative value is returned.
You can pass in a null value, indicating that you do not care about any file read changes.
Fd_set * writefds is a pointer to the fd_set structure. This collection should contain file descriptors. We want to monitor the write changes of these file descriptors,
That is, we are concerned about whether data can be written to these files. If there is a file in this collection that can be written, select will return a value greater than 0, indicating that a file is writable,
If no writable file exists, the timeout parameter is used to determine whether to time out. If the time exceeds the timeout time, select returns 0. If an error occurs, a negative value is returned.
You can pass in a null value, indicating that you do not care about any file write changes.
Fd_set * errorfds indicates the intention of the two parameters above, which is used to monitor file error exceptions. Null can be input.
Struct timeval * timeout is the select timeout time. This parameter is crucial. It can make the SELECT statement in three States. First, if null is input as a form parameter,
That is, if the time structure is not passed in, the SELECT statement is placed in the blocking state, it must wait until a file descriptor in the monitored file descriptor set changes. Second, if the time value is set to 0 s and 0 ms,
It becomes a pure non-blocking function. no matter whether the file descriptor has changed or not, it immediately returns to continue execution. If the file does not change, 0 is returned, and a positive value is returned. Third, the value of timeout is greater than 0,
This is the waiting timeout time, that is, the SELECT statement is blocked within the timeout time, and an event will be returned within the time-out time. Otherwise, no matter how long it will be returned, the return value is the same as the above.
Return Value:
Negative value: Select error positive value: some files can be read or written, or errors 0: wait for timeout, there is no readable or wrong file