zoukankan      html  css  js  c++  java
  • WSAEventSelect模型 应用实例,重写TCP服务器实例

    // WSAEvent.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include <winsock2.h>
    #include <stdio.h>
      
    #pragma comment(lib,"WS2_32")
    class CInitSock
    {
    public:
         CInitSock(BYTE minorVer=2,BYTE majorVer=2)
         {
             WSADATA wsaData;
             WORD sockVersion = MAKEWORD(minorVer,majorVer);
             if(::WSAStartup(sockVersion,&wsaData)!=0)
             {
                 exit(0);
             }
         }
         ~CInitSock()
         {
             ::WSACleanup();
         }
     };
    CInitSock initSock;
    int _tmain(int argc, _TCHAR* argv[])
    {
        //事件句柄和套接字句柄表
        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);
            //对每个事件调用函数,确定它的状态
            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
                {
                    //获取到来的通知消息,自动重置受信事件
                    WSANETWORKEVENTS event;
                    ::WSAEnumNetworkEvents(sockArray[i],eventArray[i],&event);
                    if(event.lNetworkEvents & FD_ACCEPT)
                    {
                        if(event.iErrorCode[FD_ACCEPT_BIT] == 0)
                        {
                            if(nEventTotal>WSA_MAXIMUM_WAIT_EVENTS)
                            {
                                printf("Too many connections!");
                                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)
                    {
                        if(event.iErrorCode[FD_ACCEPT_BIT] == 0)
                        {
                            char szText[256];
                            int nRecv = ::recv(sockArray[i],szText,strlen(szText),0);
                            if(nRecv > 0)
                            {
                                szText[nRecv] = '\0';
                                printf("接收到数据:%s\n",szText);
                            }
                        }
                    }
                    else if(event.lNetworkEvents & FD_CLOSE)
                    {
                        if(event.iErrorCode[FD_ACCEPT_BIT] == 0)
                        {
                            ::closesocket(sockArray[i]);
                            for(int j=i;j<nEventTotal-1;j++)
                            {
                                eventArray[j] = eventArray[j+1];
                                sockArray[j] = sockArray[j+1];
                            }
                            nEventTotal--;
                        }
                    }
                    else if(event.lNetworkEvents & FD_WRITE)
                    {
    
                    }
                }
            }
    
        }
        return 0;
    }
  • 相关阅读:
    asp.net禁用頁面緩存
    SQL排序方法,EXEC法和CASE WHEN法
    Web Service 基础连接已经关闭的解决方案
    用CSS写TABLE边框
    SQL2000分页存储过程,针对表,2005有自带的row_number
    GridView RowCommand事件中取得當前行
    取得Repeter中數據項,如TR
    FireFox自动撑高层解决方案
    PostgreSql 添加语言语法
    CSS设置图片居中
  • 原文地址:https://www.cnblogs.com/xing901022/p/2722065.html
Copyright © 2011-2022 走看看