您的位置:首页 > 其它

WSAEventSelect模型

2014-09-18 16:21 453 查看
//The
WSACreateEvent function creates a new event object.
WSAEVENT WSACreateEvent(void);

//The WSAEventSelect
function specifies an event object to be associated with the specified set of FD_XXX network events.
int WSAEventSelect(

  __in          SOCKET s,

  __in          WSAEVENT hEventObject,

  __in          long
lNetworkEvents

);

//The WSAWaitForMultipleEvents
function returns when one or all of the specified event objects are in the signaled state, when the time-out interval expires, or when an I/O completion routine has executed.
DWORD WSAWaitForMultipleEvents(

  __in          DWORD cEvents,

  __in          const
WSAEVENT* lphEvents,

  __in          BOOL fWaitAll,

  __in          DWORD dwTimeout,

  __in          BOOL fAlertable

);

//The WSAEnumNetworkEvents
function discovers occurrences of network events for the indicated socket, clear internal network event records, and reset event objects (optional).
int

WSAEnumNetworkEvents(

  __in          SOCKET s,

  __in          WSAEVENT hEventObject,

  __out         LPWSANETWORKEVENTS lpNetworkEvents

);
 
 
//////////////////////////////////////////////////
// WSAEventSelect文件

#include "WSAInit.h"

#include <stdio.h>

#include <iostream>

#include <windows.h>

// 初始化Winsock库
CWSAInit theSock;

int main()

{

    //
事件句柄和套节字句柄表
    WSAEVENT    eventArray[WSA_MAXIMUM_WAIT_EVENTS];

SOCKET sockArray[WSA_MAXIMUM_WAIT_EVENTS];

    int nEventTotal
=
0;

    USHORT nPort =
4567;   
//
此服务器监听的端口号

    //
创建监听套节字
    SOCKET sListen
= ::socket(AF_INET,
SOCK_STREAM, IPPROTO_TCP);   

    sockaddr_in sin;

    sin.sin_family =
AF_INET;

    sin.sin_port =
htons(nPort);

    sin.sin_addr.S_un.S_addr =
INADDR_ANY;

    if(::bind(sListen,
(sockaddr*)&sin,
sizeof(sin))
== SOCKET_ERROR)

    {

        printf(" Failed
bind() \n");

        return
-1;

    }

    ::listen(sListen, 5);

    //
创建事件对象,并关联到新的套节字
    WSAEVENT
event
= ::WSACreateEvent();

    ::WSAEventSelect(sListen, event,
FD_ACCEPT|FD_CLOSE);
    //
添加到表中
    eventArray[nEventTotal]
=
event;

    sockArray[nEventTotal] =
sListen;   

    nEventTotal++;

    //
处理网络事件
   
while(TRUE)

    {

        // 在所有事件对象上等待
       
int nIndex
= ::WSAWaitForMultipleEvents(nEventTotal,
eventArray, FALSE, WSA_INFINITE, FALSE);

        //
对每个事件调用WSAWaitForMultipleEvents函数,以便确定它的状态
        nIndex
= nIndex
- WSA_WAIT_EVENT_0;

        for(int
i=nIndex; i<nEventTotal;
i++)

        {

            nIndex =
::WSAWaitForMultipleEvents(1,
&eventArray[i], TRUE,
1000, FALSE);

            if(nIndex
== WSA_WAIT_FAILED
|| nIndex
== WSA_WAIT_TIMEOUT)

            {

                continue;

            }

            else

            {

                //
获取到来的通知消息,WSAEnumNetworkEvents函数会自动重置受信事件
                WSANETWORKEVENTS
event;

                ::WSAEnumNetworkEvents(sockArray[i], eventArray[i], &event);

                if(event.lNetworkEvents
& FD_ACCEPT)               
// 处理FD_ACCEPT通知消息
                {

                    if(event.iErrorCode[FD_ACCEPT_BIT]
==
0)

                    {

                        if(nEventTotal
> WSA_MAXIMUM_WAIT_EVENTS)

                        {

                            printf("
Too many connections! \n");

                            continue;

                        }

                        SOCKET sNew =
::accept(sockArray[i], NULL, NULL);

                        WSAEVENT event
= ::WSACreateEvent();

                        ::WSAEventSelect(sNew, event,
FD_READ|FD_CLOSE|FD_WRITE);

                        //
添加到表中
                        eventArray[nEventTotal]
=
event;

                        sockArray[nEventTotal] =
sNew;   

                        nEventTotal++;

                    }

                }

                else
if(event.lNetworkEvents
& FD_READ)           
// 处理FD_READ通知消息
                {

                    if(event.iErrorCode[FD_READ_BIT]
==
0)

                    {

                        char
szText[256];

                        int
nRecv = ::recv(sockArray[i],
szText, 256,
0);

                        if(nRecv
>
0)               

                        {

                            szText[nRecv] =
0;

                            printf("接收到数据:%s
\n", szText);

                        }

                    }

                }

                else
if(event.lNetworkEvents
& FD_CLOSE)       
// 处理FD_CLOSE通知消息
                {

                    if(event.iErrorCode[FD_CLOSE_BIT]
==
0)

                    {

                        ::closesocket(sockArray[i]);

                        for(int
j=i; j<nEventTotal-1;
j++)

                        {

                            eventArray[j] =
eventArray[j+1];

                            sockArray[j] =
sockArray[j+1];   

                        }

                        nEventTotal--;

                        i--;

                    }

                }

                else
if(event.lNetworkEvents
& FD_WRITE)       
// 处理FD_WRITE通知消息
                {

                }

            }

        }

    }

    return
0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: