Objective:
In many articles that compare various network models, whenever you mention a select model, the select is limited to the number of polled sockets, which is the fd_setsize value defined in the System header file (for example, 64). But in fact this is not really a limitation.
The folk prescription of C language:
In the C language world there is a technique for the partial gate of the structure, for example:
typedef struct _str_type
{
int _len;
char _s[1];
} str_type;
Str_type is used to save strings (I'm just giving an example, in fact, this structure is useless), at first glance Str_type can only save strings of length 1 (' "). However, by writing down the following code, you will break through this limitation:
int str_len = 5;
str_type *s = (str_type*) malloc( sizeof( str_type ) + str_len - 1 );
//
free( s );
The principle of this technique is very simple, because _s is just at the end of the structure, so you can assign a continuous space for it, as long as the attention to the use of pointers, this is not the code of evil. But there is a limit to this technique, and the str_type-defined variable must be assigned to the heap, otherwise it will destroy the stack. In addition, members that need to grow dynamically need to be at the end of the structure. Finally, one caveat is that this is a C-language trick, and if your structure contains C + + stuff, this technique will no longer be safe (<inside the C + + object model>).
In fact, select can also do this:
In fact, because select involves Fd_set is a structure that fully satisfies the above requirements:
winsock2.h :
typedef struct fd_set {
u_int fd_count; /**//* how many are SET? */
SOCKET fd_array[FD_SETSIZE]; /**//* an array of SOCKETs */
} fd_set;
However, if you use the above techniques to increase the number of fd_array (that is, the number of sockets saved), then those macros about Fd_set may not be available, such as Fd_set.
Winsock2.h:
#define FD_SET (FD, SET) do {\
U_int __i; \
for (__i = 0; __i < ((fd_set FAR *) (set))->fd_count; __i++) {\
if ((Fd_set FAR *) (SET))->fd_array[__i] = = (FD)) {\
Break \
} \
} \
if (__i = = (Fd_set FAR *) (SET))->fd_count) {\
if ((Fd_set FAR *) (SET))->fd_count < fd_setsize) {\
((Fd_set FAR *) (SET))->fd_array[__i] = (FD); \
((Fd_set FAR *) (set))->fd_count++; \
} \
} \
} while (0)