The role of the SELECT function:
Select () in the socket programming is still more important, but for beginners of the socket is not too fond of using Select () to write programs, they just used to write such as Conncet (), accept (), recv () Or recvfrom such a blocking program (the so-called blocking mode block, as the name implies, is the process or thread execution to these functions must wait for an event to occur, if the event does not occur, the process or thread is blocked, the function can not immediately return). However, using Select () can complete non-blocking (so-called nonblocking mode Non-block, that is, the process or thread executes this function without having to wait for the event to occur, and once the execution is returned, the return value is different to reflect the function's performance. If the event occurs in the same way as blocking, if the event does not occur, return a code that tells the event not to occur, and the process or thread continues to execute, so that it works efficiently, and it can monitor the change of the file descriptor we need to monitor-read-write or exception.
Select function Format:
The format of the Select () function (referred to as the Berkeley socket programming under the UNIX system, and the difference under Windows, explained in a moment):
Unix System explained below:
int Select (int maxfdp, fd_set* Readfds, fd_set* Writefds, fd_set* Errorfds, struct timeval* timeout);
The two structures are described first:
First: struct fd_set can be understood as a collection, this collection is stored in the file descriptor (descriptor), that is, the file handle, this can be what we call the ordinary meaning of the file, of course, UNIX under any Device, pipeline, FIFO, etc. are file forms, All included, so, without a doubt, a socket is a file, and 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*). A moment to illustrate.
Second: struct Timeval is a commonly used structure that represents time values, has two members, one is the number of seconds, and the other is the number of milliseconds.
Explain the parameters of select in detail:
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 ! This parameter value does not matter in Windows and can be set incorrectly.
fd_set* Readfds is a pointer to the FD_SET structure, which should include the file descriptor, we want to monitor the read changes of these file descriptors, that is, we care whether the data can be read from these files, if there is a file in this collection is readable, Select returns a value greater than 0, indicating that the file is readable, and if there is no readable file, the timeout parameter is used to determine whether to time out, and if timeout is exceeded,select returns 0 if an error returns a negative value. You can pass in a null value to indicate that you do not care about any file read changes.
fd_set* Writefds is a pointer to the FD_SET structure, which should include the file descriptor, we want to monitor the write changes of these file descriptors, that is, we care about whether the data can be written to these files, if there is a file in this collection can be written, Select returns a value greater than 0 indicating that a file is writable, and if there is no writable file, the timeout is determined based on timeout, and if timeout is exceeded,select returns 0 if an error returns a negative value. You can pass in a null value to indicate that you do not care about any file write changes.
Fe_set* Errorfds with the above two parameters to monitor file error exceptions.
The struct timeval* timeout is the time-out for Select, which is critical, which allows the select to be in three states.
First: If NULL is passed in as a parameter, that is, the time structure is not passed in, the select is put in a blocking state , it must wait until one of the file descriptors in the monitor file descriptor collection has changed;
Second: If the time value is set to 0 seconds and 0 milliseconds, it becomes a purely non-blocking function , regardless of whether the file descriptor changes, immediately return to continue execution, the file has no change return 0, there is a change to return a positive value;
Third: Timeout value is greater than 0, this is the waiting time-out period, that is, select in timeout time block, the timeout period has the arrival of the event to return, otherwise after the timeout anyway must return, the return value with the above.
The Select function returns the value:
Negative value:Select Error
Positive values: Some files are read-write or error-prone
0: Wait timeout, no writable or incorrect files
Explained under Windows platform:
1, Function prototype:
int Select (int Nfds, fd_set* Readfds, fd_set* Writefds, fd_set* Exceptfds, const struct timeval* timeout);
2, Parameters:
Nfds: This parameter is ignored, only play a compatible role, set to 0;
Readfds: (optional) pointer, pointing to a set of interfaces waiting for readability check;
Writefds: (optional) pointer, pointing to a set of interfaces waiting for a writable check;
Exceptfds: (optional) pointer, pointing to a set of interfaces waiting for error checking;
Timeout: The maximum wait time for this function, or null for a blocking operation.
3, return value:
(1)the Select () call returns the total number of descriptive words that are in the ready state and are already contained in the FD_SET structure;
(2) returns 0 if the timeout is exceeded;
(3) Otherwise, the SOCKET_ERROR error is returned, and the application can get the corresponding error code via WSAGETLASTERROR ().
4, Note:
This function is used to determine the state of one or more sets of interfaces. For each set of interfaces, the caller can query its readability, writeable, and error status information. A fd_set structure is used to represent a set of interfaces waiting to be inspected. When the call returns, the structure has a subset of the set of interface groups that meet certain conditions, and Select () returns the number of socket interfaces that satisfy the condition. There is a set of macros available for fd_set operations, which are compatible with Berkeley Unix software, but the internal expression is completely different.
The Readfds parameter identifies the set of interfaces awaiting readability checks. If the socket is in the listening listen () state, the socket is identified as readable if a connection request arrives, so that an accept () call is guaranteed to be complete without blocking. For other sets of interfaces, readability means that there is queued data for reading. Or for the SOCK_STREAM type socket interface, the virtual socket interface relative to the set of interfaces is closed, so the recv () or recvfrom () operation can be done without blocking. If the virtual circuit is "gracefully" aborted, then recv () does not read the data immediately, and if the virtual circuit is forcibly reset, recv () will return immediately with a wsaeconnreset error. If the So_oobinline option is set, the out-of-band data is checked for presence (see setsockopt ()).
The Writefds parameter identifies the set of interfaces waiting for a writable check. If a set of interfaces is connected (non-blocking), writable means that the connection is successfully established. If the socket is not in the Connect () call, the writeable means that the Send () and sendto () calls will be non-blocking complete. (It does not indicate how long this guarantee is effective, especially in multithreaded environments).
The Exceptfds parameter identifies the set of interfaces that wait for out-of-band data presence or error condition checking. Note that if you set the So_oobinline option to false false, you can only use this method to check the presence or absence of out-of-band data. For So_stream type socket interfaces, connection aborts and keepalive errors caused by the remote will be used as meaning errors. If the socket interface is connecting to connect () (non-blocking mode), the failure of the connection attempt will be reflected in the Exceptfds parameter.
If you are not interested in any of the group classes in Readfds, Writefds, or Exceptfds, you can set it to null.
Four macros are defined in the Winsock2.h header file to manipulate the descriptor set. The fd_setsize variable is used to determine the maximum number of descriptors in a collection (the fd_setsize default is 64, which can be changed with a # define fd_setsize before including Winsock.h ). For internal representations, Fd_set is represented as a queue for a set of interfaces, and subsequent elements of the last valid element are inval_socket. Macros are:
FD_CLR (s,*set): Removes the description character s from the set set.
Fd_isset (S,*set): If S is a member of the set, not 0; otherwise, zero.
Fd_set (S,*set): Adds the description character s to the collection.
Fd_zero (*set): Initializes the set to an empty null.
The timeout parameter controls when the Select () completes. If the timeout parameter is a null pointer, Select () will block until a description word satisfies the condition. Otherwise, timeout points to a timeval structure that specifies how long the Select () call waits before returning. If Timeval is {0,0}, Select () returns immediately, which can be used to inquire about the state of the selected socket interface. If you are in this state, the Select () call can be considered non-blocking, and all assumptions that apply to non-blocking calls apply to it.
5, error code:
wsanotinitialised: You should first successfully call WSAStartup () before using this API.
the Wsaenetdown:windows socket interface realizes the network sub-system failure.
Wsaeinval: The time-out value is illegal.
Wsaeintr: Cancels a (blocked) call with a WSACancelBlockingCall ().
wsaeinprogress: A blocked Windows Socket interface call is running.
Wsaenotsock: An element in the description Word collection that contains a non-nested interface.
6, how to deal with
As described above, the size of the fd_setsize defined in Winsock2.h is 64, which limits the number of socket handles for Readfds, Writefds, Exceptfds, Fd_setsize. In real-world applications, you can use port groupings or redefine fd_setsize to resolve them. Add the following definition to the last line of StdAfx.h:
#define FD_SETSIZE//socket handle number
#define MAXIMUM_WAIT_OBJECTS 1024//Number of objects to wait
It is important to note that we have also redefined the other macro maximum_wait_objects, which represents the number of objects to wait. Once redefined, the program works in the field.
Use and interpretation of select function in socket communication