Select model practice in WinSock

Source: Internet
Author: User

 

The select model is the most common I/O model in Winsock. The core is to use the select function to manage I/O! The select function is used to determine whether data on a socket is readable or whether data can be written to a socket to prevent the program from being in blocking mode, during an I/O call (such as send, Recv, and accept), the system is forced to enter the "locked" State. It also prevents wsaewouldblock errors when the socket is in non-blocking mode.

Select function prototype:

Int select (
Int NFDs, // input parameter, ignore
Fd_set far * readfds, // check readability
Fd_set far * writefds, // check writability
Fd_set far * contains TFDs, // exception data
Const struct timeval far * timeout // The longest wait time for this select call
);

Return Value of the function. After the select () function is called, the return value is an interface descriptor that is ready and included in the fd_set structure. That is, it must modify the set, delete the APIs that cannot be specified. If a timeout occurs, 0 is returned. If an error occurs, socket_error is returned. The application can obtain the error code through wsagetlasterror.
Fd_set is a structure type specifier, which represents a set of specific interfaces. Its definition is as follows:

Typedef struct fd_set {
U_int fd_count;/* how many are set? */
Socket fd_array [fd_setsize];/* an array of sockets */
} Fd_set;

Timeval is a structure type, which is defined as follows:

Struct timeval {
Long TV _sec;/* seconds */
Long TV _usec;/* and microseconds */
};

If the time-out value is set to (0, 0), select returns immediately. This setting should be avoided for performance considerations.

The following is a program for testing the select () function. One server has two clients.

The following are the server programs:

# Define fd_setsize 500
# Include <winsock2.h>
# Pragma comment (Lib, "ws2_32 ")
# Include <stdio. h>
Int main ()
{
Printf ("server program... \ n ");
// ------ ① Load ----------
Wsadata;
If (wsastartup (makeword (2, 2), & wsadata )! = 0)
{
Printf ("wsastartup failed, error = [% d] \ n", wsagetlasterror ());
Return 1;
}
Else
Printf ("① loaded successfully \ n ");
// ------- ② Create a streaming socket ------------
Socket S = socket (af_inet, sock_stream, 0 );
If (S = invalid_socket)
{
Printf ("socket () failed, error = [% d] \ n", wsagetlasterror ());
Return 1;
}
Else
Printf ("② the listener set interface has been created: [% d] \ n", S );
// Place the set interface s in "non-blocking mode"
U_long U1 = 1;
Ioctlsocket (S, fionbio, (u_long *) & U1 );
// ----------- ③ Bind the local address ---------------------
Struct sockaddr_in sadd;
Sadd. sin_family = af_inet;
Sadd. sin_port = htons (5555 );
Sadd. sin_addr.s_un.s_addr = inet_addr ("192.168.31.1 ");
If (BIND (S, (sockaddr *) & sadd, sizeof (sadd) = socket_error)
{
Printf ("BIND () failed, error = [% d] \ n", wsagetlasterror ());
Return 1;
}
Else
Printf ("③ binding successful, local IP Address: [% s], Port: [% d] \ n", inet_ntoa (sadd. sin_addr), ntohs (sadd. sin_port ));
// -------------- ④ Enter the listening status -----------------
If (Listen (s, 3) = socket_error)
{
Printf ("Listen failed, error = [% d] \ n", wsagetlasterror ());
Return 1;
}
Else
Printf ("④ entering the listening status \ n ");
// -------------- ⑤ Select -------------------
// Preparations
Int x = 1;
Timeval TV;
TV. TV _sec = 20;
TV. TV _usec = 0;
Fd_set socket_jh01;
Fd_zero (& socket_jh01 );
Fd_set (S, & socket_jh01 );
Fd_set socket_jh02;
Fd_zero (& socket_jh02 );
While (true)
{
Socket_jh02 = socket_jh01;
Int sock_sum = select (0, & socket_jh02, null, null, & TV );
// ------ Success
If (sock_sum> 0)
{
For (INT I = 0; I <(INT) socket_jh02.fd_count; I ++)
{
If (socket_jh02.fd_array [I] = s)
{
If (socket_jh01.fd_count <fd_setsize)
{
Sockaddr_in CADD;
Int cadd_len = sizeof (CADD );
Socket snew = accept (S, (sockaddr *) & CADD, & cadd_len );
Fd_set (snew, & socket_jh01 );
Printf ("accept a client connection, peer address: [% s], Port: [% d] \ n", inet_ntoa (CADD. sin_addr), ntohs (CADD. sin_port ));
Printf ("sets of interfaces assigned to the client: % d \ n", snew );
}
Else
{
Printf ("too many connections \ n ");
Continue;
}
}
Else
{
Char cbuf [256];
Memset (cbuf, 0,256 );
Int crecv;
Crecv = Recv (socket_jh02.fd_array [I], cbuf, 256, 0 );
If (crecv = socket_error)
{
Printf ("the client % d may be disabled illegally !! ", Socket_jh02.fd_array [I]);
Printf ("or call Recv () failed, error = [% d] \ n", wsagetlasterror ());
Closesocket (socket_jh02.fd_array [I]);
Fd_clr (socket_jh02.fd_array [I], & socket_jh01 );
}
Else if (crecv> 0)
{
Printf ("received data to [% d]: % s \ n", socket_jh02.fd_array [I], cbuf );
Int isend;
Char sbuf [] = "Hello client! I am server ";
Isend = Send (socket_jh02.fd_array [I], sbuf, sizeof (sbuf), 0 );
If (isend = socket_error)
{
Printf ("Send () failed, error = [% d] \ n", wsagetlasterror ());
Break;
}
Else if (isend <= 0)
{
Printf ("message sending failed !! \ N ");
Break;
}
Else
Printf ("message sent to customer [% d], information length % d bytes \ n", socket_jh02.fd_array [I], isend );
}
Else
{
Printf ("client [% d] no longer sends data. Normally close the connection. The set of interfaces created for client connection will be closed !! \ N ", socket_jh02.fd_array [I]);
Closesocket (socket_jh02.fd_array [I]);
Fd_clr (socket_jh02.fd_array [I], & socket_jh01 );
}
}
} // End
} // End sock_sum
// ------------ Case 2 timeout
Else if (sock_sum = 0)
{
Printf ("number [% d] times out \ n", X );
If (x <3)
{
X ++;
Continue;
}
Else
{
Printf ("exceeds the waiting limit, exit program \ n ");
Break;
}
}
// -------------- Case 3 failed
Else
{
Printf ("select () failed, error = [% d] \ n", wsagetlasterror ());
Break;
}
} // While end
Closesocket (s );
Printf ("quit ");
Wsacleanup ();
Return 0;

}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.