[Reprint] Windows Network Programming Series 4: select model

Source: Internet
Author: User

Original article:
Http://www.51see.com/asp/bbs/public/bp_show.asp? T_id = 200308131152297103.

Let's talk about the difference between Socket mode and socket I/O model. First, it is only for Winsock. If you want to pick an egg in the bones and apply the socket concept under UNIX to this place, it is none of my business.
Socket mode: blocking socket and non-blocking socket. Or synchronous socket and asynchronous socket.
Socket model: describes how to manage the I/O behavior of a socket.
There are five I/O models provided by Winsock:
Select, wsaasyncselect, wsaeventselect, overlapped, and completion. Today, we will explain the SELECT statement.

1: select model (select model)
Let's take a look at the following sentence in detail.Code:
Int iresult = Recv (S, buffer, 1024 );
This is used to receive data. In the socket in the default blocking mode, the Recv will be blocked until there is data readable on the socket connection, after the data is read to the buffer, the Recv function will return the data, otherwise it will be blocked. In a single threadProgramThis will cause the main thread (only one default main thread in a single-threaded program) to be blocked, so that the entire program is locked here. If no data is sent, then the program will be locked forever. This problem can be solved using multiple threads. However, when multiple sockets are connected, this is not a good choice and the scalability is poor. The select model is designed to solve this problem.
Look at the code again:

Int iresult = ioctlsocket (S, fiobio, (unsigned long *) & UL );
Iresult = Recv (S, buffer, 1024 );

This Recv call will return immediately no matter whether there is data on the socket connection that can be received. The reason is that we use ioctlsocket to set the socket to non-blocking mode. However, you will find that when there is no data, the Recv does return immediately, but an error is also returned: wsaewouldblock, which means that the request operation is not completed successfully. As many people may say, Recv is called repeatedly and the returned value is checked until the result is successful. However, the efficiency is very high and the overhead is too high.
thanks to the talented Microsoft engineers who have provided us with a good solution.
first look at the select function
int select (
int NFDs,
fd_set far * readfds,
fd_set far * writefds,
fd_set far * contains TFDs,
const struct timeval far * timeout
);
the first parameter is ignored by the system. The second parameter is used to check the readability of the socket, that is, to check whether there is data readable on the socket. Similarly, the third parameter is used to check whether data can be sent. The last one is to check whether out-of-band data is readable.
for more information about the parameters, see msdn.
the last parameter is used to set the length of the select wait time. It is a structure:

Struct timeval {
Long TV _sec; // seconds
Long TV _usec; // and microseconds
};
If this structure is set to (0, 0), the Select function returns immediately.
After so long, what is the role of select?
Its role is to prevent blocking sockets from being locked, and avoid repeated wsaewouldblock errors in non-blocking sockets.
The workflow is as follows:
1: Use the fd_zero macro to initialize the fd_set we are interested in, that is, the second, third, and fourth parameters of the select function.
2: Use the fd_set macro to allocate the socket handle to the corresponding fd_set.
3: Call the select function.
4: Use fd_isset to check the socket handle. If the socket handle we are concerned about is still in the fd_set that we are about to allocate, the corresponding Io operations can be performed immediately. For example, if a socket handle assigned to the first select parameter is still in the fd_set of the first select parameter after the return result of select, it indicates that the current data has arrived, it can be read successfully immediately without being blocked.

Below is a simple server socket for the select model.

# Include "iostream. H"
# Include "winsock2.h"
# Include "windows. h"


# Define Internetaddr "127.0.0.1"
# Define Iport 5055

# Pragma Comment (Lib, "ws2_32.lib ")


Void Main ()
{
Wsadata WSA;
Wsastartup (makeword ( 2 , 2 ), & WSA );

Socket fdserver = Socket (af_inet, sock_stream, ipproto_tcp );

Struct Sockaddr_in server;
Server. sin_family = Af_inet;
Server. sin_addr.s_addr = Inet_addr (internetaddr );
Server. sin_port = Htons (iport );

Int RET = BIND (fdserver, (sockaddr * ) & Server, Sizeof (Server ));
RET = Listen (fdserver, 4 );


Socket acceptsocket;
Fd_set fdread;
Timeval TV;
Int Nsize;

While ( 1 )
{

Fd_zero ( & Fdread ); // Initialize fd_set
Fd_set (fdserver, & Fdread ); // Allocate a socket handle to the corresponding fd_set


TV. TV _sec =   2 ; // Here we plan to let the SELECT statement wait for two seconds to return, so as not to be locked or to return immediately.
TV. TV _usec =   0 ;

Select ( 0 , & Fdread, null, null, & TV );

Nsize =   Sizeof (Server );
If (Fd_isset (fdserver, & Fdread )) // If the socket handle is still in fd_set, it indicates that a CONNECT request has been sent from the client, and accept is successful immediately.
{
Acceptsocket=Accept (fdserver, (sockaddr*)&Server,&Nsize );
Break;
}

Else // There are no client CONNECT requests, so we can do other things to avoid blocking Socket programs that are not blocked by the Select method from being locked. If select is not used, when the program runs to accept, the client does not have a CONNECT request, so the program will be locked and nothing can be done.
{
//Do something
: MessageBox (null,"Waiting","Recv", Mb_iconinformation );//After other things are done, continue to check whether there are client connection requests
}
}

Char Buffer [ 128 ];
Zeromemory (buffer, 128 );

RET = Recv (acceptsocket, buffer, 128 , 0 ); // Select can also be used here. The usage is the same as above

: MessageBox (null, buffer, " Recv " , Mb_iconinformation );

Closesocket (acceptsocket );
Wsacleanup ();

Return ;

}

Basically, I personally feel that the select model is not very useful. I only used it once. I used the select method to check the timeout when I wrote the port scanner last year.
I feel that it is not very clear. Although I understand things, it is not easy to explain them clearly.

Related Article

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.