Develop a Winsock application with a large response scale using the completed port (4)

Source: Internet
Author: User

Accept connection requests

One of the most common tasks for a server is to accept connection requests from clients. The only API that uses overlapping I/O to accept connections on a socket is the acceptex () function. Interestingly, the normally synchronous acceptance function accept () returns a new socket, while the acceptex () function requires another socket as one of its parameters. This is because acceptex () is an overlapping operation, so you need to create a socket beforehand (but do not bind or connect to it) and pass this socket through the parameter to acceptex (). The following is a typical example of the use of acceptex () pseudoCode:

Do {
-Wait until the previous acceptex is complete.
-Create a new socket and associate it with the completion port.
-Set the background structure and so on.
-Send an acceptex request
} While (true );

As a highly responsive server, it must make enough acceptex calls, waiting for a client connection request to respond immediately. The number of acceptex requests that are sent depends on your server.ProgramThe expected communication traffic type. For example, if the connection rate is high (because the connection duration is short or the traffic peak occurs ), the acceptex that needs to be waited for is certainly more than the client connection that occasionally enters. It is wise to use an application to analyze traffic conditions and adjust the number of acceptex waits, rather than fixed to a certain number.

For Windows2000, Winsock provides some mechanisms to help you determine whether the number of acceptex is sufficient. This is to create an event when creating a listening socket. Use the wsaeventselect () API and register the fd_accept Event Notification to associate the socket with this event. Once the system receives a connection request, if no acceptex () in the system is waiting to accept the connection, the above event will receive a signal. With this event, you can determine whether you have issued enough acceptex () or detect an abnormal customer request (as described below ). This mechanism is not applicable to Windows NT 4.0.

One of the major advantages of using acceptex () is that you can accept client connection requests and receive data (by transmitting the lpoutputbuffer parameter) through one call. That is to say, if the client transmits data while sending a connection, your acceptex () call can return immediately after the connection is created and the client data is received. This may be useful, but it may also cause problems, because acceptex () must be returned only when all client data is received. Specifically, if you pass the lpoutputbuffer parameter while sending an acceptex () call, acceptex () is no longer an atomic operation, but a two-step process: accepting client connections, waiting for receiving data. When a mechanism is missing to notify your application of this situation: "The connection has been established and is waiting for client data ", this means that the client may only send connection requests but not data. If your server receives too many such connections, it will reject more valid client requests. This is a common form of denial-of-service (DoS) attacks.

To prevent such attacks, the connection receiving thread should check the sockets waiting in acceptex () from time to time by calling the getsockopt () function (the option parameter is so_connect_time. The option value of the getsockopt () function is set to the time when the socket is connected, or to-1 (indicating that no connection has been established for the socket ). In this case, the wsaeventselect () feature can be well utilized for this check. If the connection has been established but the data has not been received for a long time, terminate the connection by closing the socket provided to acceptex () as a parameter. Note: In most non-emergency situations, if the socket has been passed to acceptex () and is waiting, but the connection has not yet been established, your application should not close them. This is because even if these sockets are closed, for the sake of improving system performance, before the connection enters, or before the socket itself is closed, the data structure in the corresponding kernel mode will not be cleared cleanly.

The thread that sends an acceptex () call seems to be the same as the thread that completes the Port Association operation and processes other I/O completion notifications. However, do not forget to avoid blocking operations in the thread. One side of Winsock2's layered structure is that calling the upper-layer architecture of socket () or wsasocket () API may be very important (the Translator does not quite understand the original meaning, sorry ). Each acceptex () call requires the creation of a new socket, so it is best to have an independent thread dedicated to calling acceptex (), not involved in other I/O processing. You can also use this thread to execute other tasks, such as event records.

The last note about acceptex (): To implement these APIs, you do not need the Winsock2 implementation provided by other providers. This is also applicable to other Microsoft-specific APIs, such as transmitfile () and getacceptexsockaddrs (), and other APIs that may be added to the new Windows version. on Windows NT and 2000, these APIs are provided in Microsoft's underlying provider DLL (mswsock. DLL. the LIB compilation connection is called, or the pointer of the function is dynamically obtained through wsaioctl () (the option parameter is sio_get_extension_function_pointer.

If the function pointer is not obtained in advance, the function is called directly (that is, mswsock is statically connected during compilation. lib, directly calling the function in the Program), then the performance will be very affected. Because acceptex () is placed outside the Winsock2 architecture, it is forced to obtain the function pointer through wsaioctl () each time it is called. To avoid this performance loss, applications that use these APIs should call wsaioctl () to directly obtain the function pointer from the underlying provider.

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.