socket-overlapping model (overlap)

Source: Internet
Author: User

The basic design principle of the socket-overlapping model (overlap) overlay model is to have the application use an overlapping data structure to post one or more Winsock I/O requests at a time. For those submitted requests, after they are complete, the application can serve them. This model is suitable for various Windows platforms except Windows CE. The overall design of the model is based on the Win32 overlapping I/O mechanism. The mechanism can perform I/O operations on the device through the ReadFile and WriteFile two functions.

The key is to understand the "overlap" two words, that is, you send the data to the system, and then do other things yourself, when you do their own things, the system is also completing the tasks you gave him, both at the same time. When the system is complete, you will be called to give him the code or notify you. Therefore, "overlap" refers to overlapping of time.

To use the overlapped I/O model on a set of sockets, you must first create a set of statements using the WSA_FLAG_OVERLAPPED flag. As shown below:
s = WSASocket (af_inet, Sock_stream, 0, NULL, 0, wsa_flag_overlapped);
When creating a socket, if you are using the socket function instead of the WSASocket function, the WSA_FLAG_OVERLAPPED flag is set by default. The flag can be associated with the following function:

WSASend
WSASendTo
WSARecv
WSARecvFrom
WSAIoctl
AcceptEx
TransmitFile

If these functions are called with a wsaoverlapped struct, the function is immediately completed and returned, regardless of whether the socket is set to block mode. There are two main ways to manage the completion of an overlapped I/O Request: Our application guest waits for "event object Notification" or "completion routine" to process the completed request.

To write a simple overlapped I/O mode server program, the basic steps are as follows:
1) Create a set of words to start listening for connection requests on the specified port.
2) accept an incoming connection request.
3) Create a new wsaoverlapped structure for the accepted set of statements and assign an event object handle to the structure. The event object handle is also assigned to an array of events so that the WSAWaitForMultipleEvents function can be used later.
4) post an asynchronous WSARECV request on the socket, specifying the parameter as the wsaoverlapped structure. (the function usually ends with a failure, returning SOCKET_ERROR Error state wsa_io_pending).
5) An array of events using step 3), call the WSAWaitForMultipleEvents function, and wait for the event associated with the overlapping call to enter the "Messenger" state (waiting for that event to fire).
6) After the WSAWaitForMultipleEvents function is completed, the Wsaresetevent (reset event) function is called for the event array, which resets the event object and processes the completed overlapping request.
7) Use the WSAGetOverlappedResult function to determine what the return state of the overlapping call is.
8) Post another overlapping WSARECV request on the socket.
9) Repeat step 5).

The source code is attached below

Server-side code:

#include <stdio.h>
#include <Winsock2.h>
#pragma comment (lib, "Ws2_32.lib")

#define MyPort 8001
#define MYIP "127.0.0.1"
#define DATA_BUFSIZE 1024

void ShowError (const char* function);
void Main ()
{
WORD wversion = Makeword (2, 0);
Wsadata Wsdata;
Wsabuf Databuf;
DWORD eventtotal = 0;
DWORD recvbytes = 0;
DWORD bytestransferred = 0;
DWORD Flags = 0;
DWORD Index = 0;
Wsaevent Eventarray[wsa_maximum_wait_events];
Wsaoverlapped acceptoverlapped;
SOCKET Listensocket, AcceptSocket;
struct sockaddr_in addr;
int addrlen = sizeof (struct sockaddr);
Char Szbuffer[data_bufsize];

Load the socket2.0 DLL
int nresult = WSAStartup (wversion, &wsdata);
if (nresult! = 0)
{
printf ("Error in function WSAStartup ():%d\n", WSAGetLastError ());
Return
}
printf ("WSAStartup success\n");


Step 1:
Start Winsock and set up a listening socket
printf ("Create socket...\n");
Listensocket = WSASocket (af_inet, Sock_stream, 0, NULL, 0, wsa_flag_overlapped);
if (Listensocket = = Invalid_socket)
{
ShowError ("socket");
Return
}
printf ("Create socket success\n");

addr.sin_family = af_inet;
Addr.sin_port = htons (MyPort);
ADDR.SIN_ADDR.S_ADDR = inet_addr (MYIP);
printf ("Bind socket...\n");
Nresult = Bind (Listensocket, (struct sockaddr*) &addr, sizeof (struct sockaddr_in));
if (nresult = = socket_error)
{
ShowError ("bind");
Return
}
printf ("Bind socket success\n");

printf ("Listen socket...\n");
Nresult = Listen (Listensocket, 5);
if (nresult = = socket_error)
{
ShowError ("Listen");
Return
}
printf ("Listen socket success\n");

Step 2:
Accept An inbound connection
AcceptSocket = Accept (listensocket, NULL, NULL);

Step 3:
Set up an OVERLAPPED structure
Eventarray[eventtotal] = wsacreateevent ();
ZeroMemory (&acceptoverlapped, sizeof (wsaoverlapped));
Acceptoverlapped.hevent = Eventarray[eventtotal];

Databuf.len = data_bufsize;
Databuf.buf = Szbuffer;

eventtotal++;

Step 4:
Post a WSARECV request to begin receiving data on the socket
WSARecv (AcceptSocket, &databuf, 1, &recvbytes, &flags, &acceptoverlapped, NULL);

while (TRUE)
{
Step 5:
Wait for the overlapped I/O call to complete
Index = WSAWaitForMultipleEvents (Eventtotal, Eventarray, False, Wsa_infinite, false);

Step 6:
Reset the signaled event
Wsaresetevent (Eventarray[index-wsa_wait_event_0]);

Step 7:
Determine the status of the overlapped
WSAGetOverlappedResult (AcceptSocket, &acceptoverlapped, &bytestransferred, FALSE, &Flags);

First check to see whether the peer has closed the connection,
And if so, close the socket
if (bytestransferred = = 0)
{
ShowError ("Closing socket");
Closesocket (AcceptSocket);
Wsacloseevent (Eventarray[index-wsa_wait_event_0]);
Return
}

Do someting with the received data
Databuf contains the received data
printf ("Received:%s\n", databuf.buf);

Step 8:
Post another WSARECV () request on the socket
Flags = 0;
ZeroMemory (&acceptoverlapped, sizeof (acceptoverlapped));
Acceptoverlapped.hevent = Eventarray[index-wsa_wait_event_0];

Databuf.len = data_bufsize;
Databuf.buf = Szbuffer;

WSARecv (AcceptSocket, &databuf, 1, &recvbytes, &flags, &acceptoverlapped, NULL);
}

Close socket
Closesocket (Listensocket);

Uninstalling the socket2.0 DLL
WSACleanup ();
}

void ShowError (const char* function)
{
LPVOID lpMsgBuf;

FormatMessage (format_message_allocate_buffer| format_message_from_system,0, GetLastError (),
Makelangid (Lang_neutral, Sublang_default),//default language
(LPTSTR) &lpmsgbuf, 0, NULL);

printf ("Error in function%s:\n Description:%s\n", function, (char*) lpmsgbuf);

Freeing memory
LocalFree (LPMSGBUF);
}

Source: <socket-overlapping model (overlap) _focus_ Sina Blog >

socket-overlapping model (overlap)

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.