MFC_IO模型_WSAEventSelect事件选择模型

WSAEventSelect事件选择模型,什么是事件选择模型呢? 

就是咱们把客户端的socket和一个事件绑定在一起后,然后调用waitmutipleobject,然后等待函数的返回,其实跟那个线程同步差不多,

就是等待事件对象的状态改变,状态改变是什么意思呢?也就是受信和未受信,2种状态,

如果有客户端发送消息,我们就受信了,然后我们就进行处理,处理完毕后,我们就应该把事件对象进行设置到未受信,然后继续等待事件

对象的受信

WSAEventSelect事件选择模型创建的步骤,

1.新建2个数组,一个装socket,一个装事件,因为是一个事件句柄和一个socket绑定嘛,所以需要2个,还需要一个count,用来标识有多少个元素

2.进行创建线程,此线程就调用waitmutipleobject 等待事件数组的对象受信后,我们在做处理

3.在主线程或者创建一个线程进行无限的等待用户来连接,用户连接后,我们就把用户的socket放在咱们的socket数组里面,还要创建一个事件对象放在事件数组里面

4.继续重复第三步

 

上代码:

 

 

DWORD WINAPI WorkerThread(LPVOID lpParam)//工作者线程
{
    Cselect服务端Dlg* t = (Cselect服务端Dlg*)lpParam;
    int  ret, index;
    WSANETWORKEVENTS NetworkEvents;//事件对象
    char buff[1024]={0};
    while (TRUE)
    {
        //关键API
        ret = WSAWaitForMultipleEvents(t->TotalConn, t->g_CliEventArr, FALSE, 1000, FALSE);//多少个元素,事件对象数组的指针,是不是全部等待完毕?,等待多长时间?,最后一个参数为FALSE(没用)

        if (ret == WSA_WAIT_FAILED || ret == WSA_WAIT_TIMEOUT)//等待超时的时候,进行继续等待
        {
            continue;//如果返回值是错误或是超时,那么继续
        }

        index = ret - WSA_WAIT_EVENT_0;//取出发生事件的对应项,成功
        WSAEnumNetworkEvents(t->g_CliSocketArr[index], t->g_CliEventArr[index], &NetworkEvents);//指定的socket,事件对象(如果传入的话,系统自动帮我们设置为非传信),最后一个参数取状态

        if (NetworkEvents.lNetworkEvents & FD_READ)//取得FD_READ的方法//是否是读?
        {

            ret = recv(t->g_CliSocketArr[index], buff, sizeof(buff)*sizeof(char), 0);//接收
            if (ret == 0 || (ret == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET))//接受失败,就断开socket连接
            {
                t->Cleanup(index);//掉线\退出的错误则处理
            }
            else
            {
                USES_CONVERSION;
                buff[ret] = '\0';//传过来的编码好像是ansi码,我们得转换一下
                char* temp = (char*)A2W(buff);
                CString str;
                str.Format(_T("客户端发送过来的内容是:%s"),temp);
                AfxMessageBox(str);
                //send(g_CliSocketArr[index], szMessage, strlen(szMessage), 0);//返回客户端原信息
            }
        }
        if (NetworkEvents.lNetworkEvents & FD_CLOSE)//客户端关闭
        {
            t->Cleanup(index);
        }
    }
    return 0;
}


void Cselect服务端Dlg::OnBnClickedButton1()
{
    WSADATA     wsaData;

    int         iaddrSize = sizeof(SOCKADDR_IN);
    DWORD       dwThreadId;
    // Initialize Windows socket library
    //装载套接字库
    WSAStartup(0x0202, &wsaData);
    // Create listening socket
    //创建套接字
    sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    // Bind
    //绑定
    CString ip;
    this->GetDlgItemText(IDC_EDIT5,ip);
    USES_CONVERSION;
    local.sin_addr.S_un.S_addr = inet_addr(W2A(ip.GetBuffer()));
    ip.ReleaseBuffer();
    local.sin_family = AF_INET;
    this->GetDlgItemText(IDC_EDIT2,ip);
    local.sin_port = htons(_tstoi(ip.GetBuffer()));
    ip.ReleaseBuffer();
    bind(sListen, (struct sockaddr *)&local, sizeof(SOCKADDR_IN));
    // Listen
    //监听
    listen(sListen, 1000);
    AfxMessageBox(_T("监听成功"));
    iAddrSize = sizeof(SOCKADDR_IN);
    //DWORD threadId;
    CreateThread(NULL, 0, WorkerThread, this, 0, NULL);



    while (TRUE)
    {
        // Accept a connection
        //接受连接
        sClient = accept(sListen, (struct sockaddr *)&client, &iaddrSize);
     //我们可以在这里判断,如果,TotalConn+1%64 = 0,说明已经超过64个客户了,我们就新创建一个线程进行监听,顺便也新创建2个数组,socket和事件
     //可以用list来保存这2个对象,咱们可以定义一个对象,用来保存socket数组和事件数组,然后在加入到List当中,然后在线程里面判断,我需要等待哪一个socket数组呢?
     //list一个元素就相当于一个线程嘛,
     //因为采用这种IO异步,一个线程只可以等待64个嘛,所以我们得新建一个新的线程去等待新的64个socket客户端嘛,
//记住一个线程只可以等待64个客户端  
g_CliSocketArr[TotalConn]
= sClient;//保存到套接字数组 g_CliEventArr[TotalConn] = WSACreateEvent();//创建一个事件对象并保存到数组 WSAEventSelect(g_CliSocketArr[TotalConn],g_CliEventArr[TotalConn],FD_READ | FD_CLOSE);//把socket和创建的事件句柄关联在一起 TotalConn++; } } void Cselect服务端Dlg::Cleanup(int index)//关闭处理 { closesocket(g_CliSocketArr[index]);//关闭对应数组下标的套接字 WSACloseEvent(g_CliEventArr[index]);//关闭对应的事件对象 if (index < TotalConn - 1)//判断是不是只有一个socket, { g_CliSocketArr[index] = g_CliSocketArr[TotalConn - 1];//把最后一个socket放到需要关闭的这个位置 g_CliEventArr[index] = g_CliEventArr[TotalConn - 1];//把事件句柄也给改变了 } TotalConn--;//然后把数组下标的量减1,从而整个数组变少了。 }

 

 

posted @ 2013-08-10 22:34  宝贝,我永远都在  阅读(762)  评论(0)    收藏  举报