Windows平台下 WSAEventSelect模型 服务器

// Socket 编程  WSAEventSelect 编程模型

// 事件驱动模型
#include   "stdafx.h"
#include   <winsock2.h>
#include   <iostream>
#pragma   comment (   lib ,   "ws2_32.lib"   )

using   namespace   std ;


int   _tmain (   int   argc   ,   _TCHAR *   argv [])
{
        WSAEVENT     eventArray   [ WSA_MAXIMUM_WAIT_EVENTS ];
        SOCKET       sockArray   [ WSA_MAXIMUM_WAIT_EVENTS ];
        int          nEventTotal   = 0;
        USHORT       nPort          = 9990;

        WSADATA     ws   ;
        WSAStartup (   MAKEWORD   ( 2, 2 ), & ws   );

        SOCKET   ListenSocket   = :: socket (   AF_INET ,   SOCK_STREAM   ,   IPPROTO_TCP   );
        if (   INVALID_SOCKET   ==   ListenSocket   )
     {
             cout << "Socket Failed !"   << " Reson:" <<   WSAGetLastError   ()<< endl   ;
             WSACleanup ();
             return   -1;
     }

        //   设置服务器 Socket   地址
        sockaddr_in   addrServ   ;
        addrServ . sin_family      =   AF_INET ;
        addrServ . sin_port        =   htons ( 9990 );     //   服务器端口号
        addrServ . sin_addr   . S_un .   S_addr   =   htonl   (   INADDR_ANY   );

        //   绑定
        int       retVal   ;
        retVal   =   bind   (   ListenSocket , (   const   struct   sockaddr   *)& addrServ   ,   sizeof (   SOCKADDR_IN   ) );
        if (   SOCKET_ERROR   ==   retVal   )
     {
             cout << "bind failed !"   << "   Reson: " <<   WSAGetLastError   ()<< endl   ;
             closesocket (   ListenSocket   );
             WSACleanup ();
             return   -1;
     }

        //   监听
        retVal   =   listen   (   ListenSocket , 5 );
        if (   SOCKET_ERROR   ==   retVal   )
     {
             cout << "listen failed !"   << " Reson:" <<   WSAGetLastError   ()<< endl   ;
             closesocket (   ListenSocket   );
             WSACleanup ();
             return   -1;
     }

        WSAEVENT     myevent   = :: WSACreateEvent ();
     ::   WSAEventSelect (   ListenSocket   ,   myevent ,   FD_ACCEPT   |   FD_CLOSE   );
        eventArray [ nEventTotal   ] =   myevent ;
        sockArray [ nEventTotal   ]  =   ListenSocket ;
     ++   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   )
          {
                 int   ret   ;
                 ret   = :: WSAWaitForMultipleEvents   ( 1, & eventArray   [ i ],   TRUE , 1000,   FALSE   );
                 if (   ret   ==   WSA_WAIT_FAILED   ||   ret   ==   WSA_WAIT_TIMEOUT   )
                      continue ;
                 else
              {
                      //   获取到来的通知消息   WSAEnumNetworkEvents   函数自动重置授信事件
                      WSANETWORKEVENTS   event1   ;
                   ::   WSAEnumNetworkEvents   (   sockArray [   i ],   eventArray   [ i ], &   event1   );
                      if (   event1   . lNetworkEvents   &   FD_ACCEPT   )
                   {
                           //   如果处理 FD_ACCEPT   消息时没有错误
                           if (   event1   . iErrorCode [   FD_ACCEPT_BIT ] == 0 )
                        {
                                //   连接太多,暂时不处理
                                if (   nEventTotal   >   WSA_MAXIMUM_WAIT_EVENTS   )
                             {
                                     cout << "Too Many Connection" <<   endl ;
                                     continue ;
                             }

                                SOCKET   sNew   = :: accept (   sockArray   [ i ],   NULL ,   NULL   );
                                WSAEVENT   newEvent   = :: WSACreateEvent   ();
                             ::   WSAEventSelect (   sNew   ,   newEvent   ,   FD_READ   |   FD_WRITE   |   FD_CLOSE   );
                                eventArray [ nEventTotal   ] =   newEvent   ;
                                sockArray [ nEventTotal   ]  =   sNew ;
                                nEventTotal ++;
                        }
                   }
                      else   if   (   event1 .   lNetworkEvents   &   FD_READ   )
                   {
                           //   如果 FD_READ   消息时没有错误
                           if (   event1   . iErrorCode [   FD_READ_BIT ] == 0 )
                        {
                                char   szText   [256];
                                int     nRecv   = :: recv (   sockArray   [ i ],   szText ,   strlen   ( szText ), 0 );
                                if (   nRecv   > 0 )
                             {
                                     szText [ nRecv   ] =   '\0' ;
                                     cout << "   接收到数据   : " <<   szText << endl   ;
                                     strcpy (   szText   ,   "msg receive ." );
                                     int   nSnd   = :: send (   sockArray   [ i ],   szText ,   strlen   (   szText   ), 0 );
                             }
                        }

                   }
                      else   if   (   event1 .   lNetworkEvents   &   FD_CLOSE   )
                   {
                           if (   event1   . iErrorCode [   FD_CLOSE_BIT ] == 0 )
                        {
                             ::   closesocket ( sockArray   [ i ]);
                                for (   int   j   =   i ;   j   <   nEventTotal   - 1;   j ++ )
                             {
                                     sockArray [ j   ]  =   sockArray   [ j +1];
                                     eventArray [ j   ] =   eventArray   [ j +1];
                             }

                             --   nEventTotal ;
                        }
                   }
                      else   if   (   event1 .   lNetworkEvents   &   FD_WRITE   )
                   {
                           if (   event1   . iErrorCode [   FD_WRITE_BIT ] == 0 )
                        {
                                char   szText   [256] =   "msg received." ;
                                int   nSnd   = :: send (   sockArray   [ i ],   szText ,   strlen   ( szText ), 0 );
                        }
                   }
              }
          }
     }

        closesocket ( ListenSocket   );
        system (   "pause"   );
        return   0;
}
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值