eventselect網絡模型

#include<iostream>
#include<winsock2.h>


#pragma comment(lib,"ws2_32.lib")


using std::cout;
using std::endl;

const int PORT = 10086;
const int MAX_DATA = 65535;
SOCKET sockListen = INVALID_SOCKET;
SOCKET sockArr[WSA_MAXIMUM_WAIT_EVENTS] = { 0 };
WSAEVENT EventArr[WSA_MAXIMUM_WAIT_EVENTS] = { 0 };
int nSock = 0;
bool InitEnv()
{
    WSADATA wsaData;
    //初始化環境
    if (WSAStartup(MAKEWORD(2, 2), &wsaData))
    {
        cout << "WSAStartup failed\n";
        return false;
    }
    //創建socket
    if (SOCKET_ERROR == (sockListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)))
    {
        cout << "Create socket failed\n";
        return false;
    }
    //綁定
    sockaddr_in addrSrv;
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_addr.S_un.S_addr = INADDR_ANY;
    addrSrv.sin_port = htons(PORT);
    if (SOCKET_ERROR == bind(sockListen, (sockaddr*)&addrSrv, sizeof(addrSrv)))
    {
        cout << "bind failed\n";
        return false;
    }
    //關聯事件
    WSAEVENT eventListen = WSACreateEvent();
    WSAEventSelect(sockListen, eventListen, FD_ACCEPT | FD_CLOSE);
    //監聽
    if (SOCKET_ERROR == listen(sockListen, SOMAXCONN))
    {
        cout << "listen failed,err:" << WSAGetLastError() << endl;
        return false;
    }
    sockArr[nSock] = sockListen;
    EventArr[nSock] = eventListen;
    ++nSock;
    return true;
}

void HandleEvent()
{
    WSANETWORKEVENTS NetWorkEvent;
    while (1)
    {
        DWORD dwIndex = WSAWaitForMultipleEvents(nSock, EventArr, FALSE, 100, FALSE);
        if (WSA_WAIT_TIMEOUT == dwIndex)
            continue;
        WSAEnumNetworkEvents(sockArr[dwIndex - WSA_WAIT_EVENT_0], EventArr[dwIndex - WSA_WAIT_EVENT_0], &NetWorkEvent);
        //新客戶端連接
        if (NetWorkEvent.lNetworkEvents&FD_ACCEPT)
        {
            if (NetWorkEvent.iErrorCode[FD_ACCEPT_BIT] != 0)
                continue;
            SOCKET sockClient = accept(sockArr[dwIndex - WSA_WAIT_EVENT_0], NULL, NULL);
            if (INVALID_SOCKET == sockClient)
                continue;
            WSAEVENT newEvent = WSACreateEvent();
            WSAEventSelect(sockClient, newEvent, FD_READ | FD_WRITE | FD_CLOSE);
            sockArr[nSock] = sockClient;
            EventArr[nSock] = newEvent;
            ++nSock;
        }
        //客戶端寫
        if (NetWorkEvent.lNetworkEvents&FD_READ)
        {
            if (NetWorkEvent.iErrorCode[FD_READ_BIT] != 0)
                continue;
            char szData[MAX_DATA] = { 0 };
            if (SOCKET_ERROR == recv(sockArr[dwIndex - WSA_WAIT_EVENT_0], szData, MAX_DATA, 0))
                continue;
            cout << szData << endl;
        }
        //客戶端讀
        if (NetWorkEvent.lNetworkEvents&FD_WRITE)
        {
            if (NetWorkEvent.iErrorCode[FD_WRITE_BIT] != 0)
                continue;
            char szData[MAX_DATA] = "hello world";
            if (SOCKET_ERROR == send(sockArr[dwIndex - WSA_WAIT_EVENT_0], szData, MAX_DATA, 0))
                continue;
        }
        //斷開連接
        if (NetWorkEvent.lNetworkEvents&FD_CLOSE)
        {
            if (NetWorkEvent.iErrorCode[FD_CLOSE_BIT] != 0)
                continue;
            closesocket(sockArr[dwIndex - WSA_WAIT_EVENT_0]);
        }
    }
}
int main()
{
    if (InitEnv())
        HandleEvent();

    closesocket(sockListen);
    WSACleanup();
    system("pause");
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章