First, I/O is clearly divided into blocking I/O and non-blocking I/O. To improve performance, I/O model 5 is proposed in Windows network programming. The true purpose of the select design is:
1. Prevent the application from being forced to "locked" during an IO binding call when the socket is in locked mode;
2. Prevent wsaewouldblock errors when the socket is in non-blocking mode.
Explanation 2:
In non-blocking mode, functions such as accept will return immediately. The error is wsaewouldblock, and then the accept is called cyclically until a connection is established.
The Calling effect is not good, so using select can prevent wsaewouldblock errors. The example code of 2 is as follows:
// Servertest. CPP: defines the entry point for the console application. <br/> // <br/> # include "stdafx. H "<br/> int main (INT argc, char * argv []) <br/>{< br/> word wversionrequested; <br/> wsadata; <br/> int err; </P> <p> wversionrequested = makeword (2, 2); </P> <p> err = wsastartup (wversionrequested, & wsadata ); <br/> If (Err! = 0) {<br/>/* tell the user that we cocould not find a usable */<br/>/* Winsock DLL. */<br/> return 0; <br/>}</P> <p>/* confirm that the Winsock DLL supports 2. 2. */<br/>/* Note that if the DLL supports Versions greater */<br/>/* than 2.2 In addition to 2.2, it will still return */<br/>/* 2.2 in wversion since that is the version we */<br/>/* requested. */</P> <p> If (lobyte (wsadata. wversion )! = 2 | <br/> hibyte (wsadata. wversion )! = 2) {<br/>/* tell the user that we cocould not find a usable */<br/>/* Winsock DLL. */<br/> wsacleanup (); <br/> return 0; <br/>}</P> <p> const int local_port = 5000; <br/> socket listenfd = socket (af_inet, sock_stream, ipproto_tcp); <br/> If (invalid_socket = listenfd) <br/> {<br/> printf ("create socket failed. error code is: % d/N ", wsagetlasterror (); <br/> return 0; <br/>}< br/> struct sockaddr_in localaddr; <br/> memset (& localaddr, 0, sizeof (localaddr); </P> <p> localaddr. sin_family = af_inet; <br/> localaddr. sin_port = htons (local_port); <br/> localaddr. sin_addr.s_addr = inet_addr ("192.168.0.10"); <br/> int iresult = BIND (listenfd, (const struct sockaddr far *) & localaddr, sizeof (localaddr )); <br/> If (socket_error = iresult) <br/> {<br/> printf ("bind failed, error code: % d. /n ", wsagetlasterror (); <br/> return 0; <br/>}</P> <p> iresult = listen (listenfd, 128 ); <br/> If (socket_error = iresult) <br/> {<br/> printf ("Listen failed. error code is: % d/N ", wsagetlasterror (); <br/> return 0; <br/>}< br/> u_long switchon = 1; <br/> iresult = ioctlsocket (listenfd, fionbio, (u_long far *) & switchon); <br/> If (socket_error = iresult) <br/> {<br/> printf ("ioctlsocket failed. error code is: % d/N ", wsagetlasterror (); <br/> return 0; <br/>}< br/> socket acceptfd; <br/> struct sockaddr_in clientaddr; <br/> memset (& clientaddr, 0, sizeof (clientaddr); <br/> int iaddrlength = sizeof (clientaddr ); </P> <p> while (true) <br/> {<br/> fd_set readfd; <br/> fd_zero (& readfd ); <br/> fd_set (listenfd, & readfd); <br/> iresult = select (listenfd, & readfd, null, null ); <br/> If (socket_error = iresult) <br/> {<br/> printf ("select failed, error code is: % d/N ", wsagetlasterror (); <br/> continue; <br/>}< br/> acceptfd = accept (listenfd, (struct sockaddr far *) & clientaddr, & iaddrlength ); <br/> If (invalid_socket = acceptfd) <br/>{< br/> printf ("Accept failed. error code is: % d/N ", wsagetlasterror (); <br/> // sleep (100); <br/> continue; <br/>}< br/> // do something. <br/> //....... <br/> closesocket (acceptfd); <br/>}< br/> closesocket (listenfd); <br/> getchar (); <br/> return 0; <br/>}< br/>