The Select () mechanism provides an fd_set data structure, which is actually a long array. Each array element can be associated with an open file handle (whether it is a socket handle, or other files, named pipelines, or device handles. The programmer completes the connection establishment. When select () is called, the content of fd_set is modified by the kernel according to the IO status, this will notify the socket or file that the select () process is executed to be readable. The specific explanation is as follows:
# Include <sys/types. h>
# Include <sys/times. h>
# Include <sys/select. h>
Int select (NFDs, readfds, writefds, limit TFDs, timeout)
Int NFDs;
Fd_set * readfds, * writefds, * required TFDs;
Struct timeval * timeout;
NDfS: the number of file handles monitored by the SELECT statement, depending on the number of files opened in the process. It is generally set to the maximum file number in each file to be monitored plus one.
Readfds: a collection of readable file handles monitored by select.
Writefds: a set of writable file handles monitored by select.
Except TFDs: a collection of abnormal file handles monitored by select.
Timeout: the timeout end time of this select () operation. (See/usr/sys/select. H,
Accurate to one second per million !)
When the image files in readfds or writefds are readable, writable, or time-out, this select () operation ends and returns. With the macro provided by a set of systems, programmers can determine which file is readable or writable at the end of select. Readfds is particularly useful for socket programming.Several related macros are explained as follows:
Fd_zero (fd_set * fdset): clears the contact between fdset and all file handles.
Fd_set (int fd, fd_set * fdset): Establishes the connection between the file handle FD and fdset.
Fd_clr (int fd, fd_set * fdset): clears the contact between the file handle FD and fdset.
Fd_isset (int fd, fdset * fdset): Check whether the file handle FD associated with fdset is
It can be read and written.> 0 indicates that it can be read and written.
(For definition of fd_set and related macros, see/usr/include/sys/types. h)
In this way, your socket only needs to be read when there is something to read, roughly as follows:
...
Int sockfd;
Fd_set FDR;
Struct timeval timeout = ..;
...
For (;;){
Fd_zero (& FDR );
Fd_set (sockfd, & FDR );
Switch (select (sockfd + 1, & FDR, null, & timeout )){
Case-1:
Error handled by u;
Case 0:
Timeout hanled by u;
Default:
If (fd_isset (sockfd )){
Now u read or Recv something;
/* If sockfd is father and
Server socket, u can now
Accept ()*/
}
}
}
Therefore, an fd_isset (sockfd) is equivalent to a FD readable notification. For the struct timeval function, use man select.Different timeval settings enable Select () to display three features: time-out completion, no time-out blocking, and round-robin.Because timeval can be accurate to one second per million, Windows settimer () is nothing. You can use select () to make a super clock.
--
This article discusses how to use select () to detect socket shutdown by the other Party:
The local socket is still readable, because when the socket of the other party is closed, a disconnect notification message will be sent and will be immediately detected by select. For more information about TCP connections (three-way handshakes) and closed (two-way handshakes), see related books on TCP/IP.
For some reason, Unix does not seem to provide a notification to the process about the socket or pipe signal disabled by the other party, or the CPU is limited. In short, when the other party closes and executes Recv () or read (),-1 is returned immediately. At this time, the value of the global variable errno is 115, the corresponding sys_errlist [errno] is "Connect refused" (see/usr/include/sys/errno. h ). Therefore, in the previous (;;)... in the select () block, when something is readable, you must check the returned values of Recv () or read (). When-1 is returned, you must disable the local socket, otherwise, select () will always think that there is something to read, and the results have previously made the CPU sad to cut the pin. If you don't believe it, try: do not check the Recv () returned result, and write the received result (not actually received) to the standard output... similar problems also occur in programming of famous pipelines. Specific Handling: release a useful Socket Client source code