您的位置:首页 > 其它

Windows平台下WSAAsyncSelect 模型 服务器

2013-12-20 13:54 302 查看
#include "stdafx.h"
[align=left]#include <winsock2.h>[/align]
[align=left]#include <iostream>[/align]
[align=left]#include "winuser.h"[/align]
[align=left]#pragma comment( lib, "ws2_32.lib" )[/align]
[align=left]
[/align]
[align=left]using namespace std;[/align]
[align=left]
[/align]
[align=left]
[/align]
const int MAXDATASIZE   
= 128;
const int BACKLOG       
= 10;      // 指定等待连接队列的最大长度
const int WM_SOCKET     
= ( WM_USER +
1);
const int BUF_SIZE      
= 256;
[align=left]
[/align]
[align=left]struct _SOCKET_INFOMATION[/align]
[align=left]{[/align]
[align=left]      char    Buffer [MAXDATASIZE];     // 发送和接收数据缓冲区[/align]
[align=left]      WSABUF  DataBuf ;                 // 定义发送和接收数据缓冲区,保护缓冲区在内的长度和内容[/align]
[align=left]      SOCKET  Socket ;                  // 与客户端进行通信的 socket[/align]
[align=left]      _SOCKET_INFOMATION* Next ;        // 指向下一个Socket 信息[/align]
[align=left]};[/align]
[align=left]
[/align]
[align=left]typedef _SOCKET_INFOMATION   SOCKET_INFOMATION;[/align]
[align=left]typedef _SOCKET_INFOMATION*  LPSOCKET_INFOMATION;[/align]
[align=left]
[/align]
[align=left]SOCKET Accept;                       // 监听的SOCKET[/align]
[align=left]LPSOCKET_INFOMATION   SocketInfoList; // 所有socket 的信息列表[/align]
[align=left]char    buf[ MAXDATASIZE];[/align]
[align=left]
[/align]
[align=left]
[/align]
[align=left]BOOL                   CreateSocketInformation ( SOCKET s );[/align]
[align=left]LPSOCKET_INFOMATION    GetSocketInfomation( SOCKET s );[/align]
[align=left]HWND                   MakeWorkerWindow();[/align]
[align=left]LRESULT CALLBACK      WindowProc( HWND hwdn, UINT uMsg , WPARAM wParam, LPARAM lParam );[/align]
[align=left]
[/align]
[align=left]enum[/align]
[align=left]{[/align]
      MAIN_RETURN_ERROR          
=  -1,
      MAIN_RETURN_NORMAL         
=   0,
[align=left]};[/align]
[align=left]
[/align]
[align=left]// 创建 SOCKET[/align]
[align=left]BOOL CreateSocketInformation( SOCKET s )[/align]
[align=left]{[/align]
[align=left]      LPSOCKET_INFOMATION SI ;[/align]
[align=left]      // 为SI 分配空间[/align]
      if(
( SI =
(LPSOCKET_INFOMATION) GlobalAlloc( GPTR , sizeof ( SOCKET_INFOMATION )
) ) == NULL )
[align=left]     {[/align]
           cout<<"GlobalAlloc
Failed with Error "<< GetLastError();
[align=left]           return FALSE ;[/align]
[align=left]     }[/align]
[align=left]
[/align]
[align=left]      // 向前插入法[/align]
      SI->Socket       
= s;
      SI->Next         
= SocketInfoList;
      SocketInfoList  
= SI ;
[align=left]
[/align]
[align=left]      return TRUE ;[/align]
[align=left]}[/align]
[align=left]
[/align]
[align=left]// 调用 GetSocketInfomation 来获取 Socket 的消息[/align]
[align=left]LPSOCKET_INFOMATION    GetSocketInfomation( SOCKET s )[/align]
[align=left]{[/align]
[align=left]      LPSOCKET_INFOMATION si = SocketInfoList;[/align]
[align=left]
[/align]
[align=left]      while( si )[/align]
[align=left]     {[/align]
[align=left]           if( si ->Socket == s )[/align]
[align=left]               return si ;[/align]
[align=left]
[/align]
[align=left]           si = si ->Next;[/align]
[align=left]     }[/align]
[align=left]
[/align]
[align=left]      return NULL ;[/align]
[align=left]}[/align]
[align=left]
[/align]
HWND MakeWorkerWindow(
)
[align=left]{[/align]
[align=left]      // 定义registerClass 的注册窗口[/align]
[align=left]      WNDCLASSEX wndclass ;[/align]
[align=left]      char*   ProviderClass = "AsyncSelect";[/align]
[align=left]      HWND  Window ;[/align]
[align=left]
[/align]
[align=left]      wndclass.style = CS_HREDRAW | CS_VREDRAW;[/align]
      wndclass.cbClsExtra = wndclass. cbWndExtra =
0;
[align=left]      wndclass.hInstance = NULL;[/align]
      wndclass.hIcon     
= LoadIcon( NULL , IDI_WARNING );
      wndclass.hCursor   
= LoadCursor( NULL, IDC_ARROW );
      wndclass.hbrBackground =
(HBRUSH )GetStockObject( WHITE_BRUSH);
      wndclass.lpszMenuName  
= NULL;
[align=left]      wndclass.lpszClassName = ProviderClass;[/align]
      wndclass.lpfnWndProc =
(WNDPROC) WindowProc;
[align=left]
[/align]
      if( RegisterClassEx (
&wndclass)
== 0 )
[align=left]     {[/align]
           cout<<"RegisterClass
failed with error "<< GetLastError()<<endl ;
[align=left]           return NULL ;[/align]
[align=left]     }[/align]
[align=left]
[/align]
      if(
( Window = CreateWindow( ProviderClass, "" , WS_OVERLAPPEDWINDOW ,
[align=left]                                 CW_USEDEFAULT, CW_USEDEFAULT , CW_USEDEFAULT, CW_USEDEFAULT,[/align]
                                     NULL, NULL , NULL, NULL )
) == NULL )
[align=left]     {[/align]
           cout<<"CreateWindow
failed with error "<< GetLastError()<<endl ;
[align=left]           return NULL ;[/align]
[align=left]     }[/align]
[align=left]
[/align]
[align=left]      return Window ;[/align]
[align=left]}[/align]
[align=left]
[/align]
[align=left]LRESULT CALLBACK WindowProc( HWND hwdn, UINT uMsg , WPARAM wParam , LPARAM lParam )[/align]
[align=left]{[/align]
[align=left]      LPSOCKET_INFOMATION SocketInfo ;[/align]
[align=left]      if( uMsg == WM_SOCKET )[/align]
[align=left]     {[/align]
           if( WSAGETSELECTERROR ( lParam )
)
               cout<<"Socket
failed with error with "<< WSAGETSELECTERROR( lParam )<<endl;
[align=left]           else[/align]
[align=left]          {[/align]
               switch( WSAGETSELECTEVENT ( lParam)
)
[align=left]              {[/align]
[align=left]               case FD_ACCEPT :[/align]
[align=left]                   {[/align]
                         if( Accept = accept( wParam, NULL, NULL )
== INVALID_SOCKET )
[align=left]                              cout<<"" <<endl;[/align]
[align=left]                         else[/align]
[align=left]                        {[/align]
[align=left]                              CreateSocketInformation ( Accept );[/align]
[align=left]                              WSAAsyncSelect( Accept , hwdn, WM_SOCKET , FD_READ| FD_WRITE|FD_CLOSE );[/align]
[align=left]                        }[/align]
[align=left]                   }[/align]
[align=left]                    break;[/align]
[align=left]               case FD_READ :[/align]
[align=left]                   {[/align]
[align=left]                         SocketInfo = GetSocketInfomation ( wParam );[/align]
                         int Recv   
= recv( SocketInfo ->Socket, buf, MAXDATASIZE ,
0 );
                         buf[Recv ] 
= '\0';
                         if( Recv >
0 )
                              cout<<"Received:  %s
"<< endl;
[align=left]                   }[/align]
[align=left]                    break;[/align]
[align=left]              }[/align]
[align=left]          }[/align]
[align=left]
[/align]
[align=left]           return 0;[/align]
[align=left]     }[/align]
[align=left]
[/align]
[align=left]      return DefWindowProc ( hwdn, uMsg, wParam , lParam );[/align]
[align=left]}[/align]
[align=left]
[/align]
[align=left]
[/align]
int main( int argc , char* argv[]
)
[align=left]{[/align]
[align=left]      MSG    msg ;[/align]
[align=left]      DWORD  Ret ;[/align]
[align=left]      SOCKET socketfd ;[/align]
[align=left]      HWND   Window ;[/align]
[align=left]     [/align]
      if(
( Window = MakeWorkerWindow()
) == NULL )
[align=left]           return 0;[/align]
[align=left]
[/align]
[align=left]      WSADATA wsaData ;[/align]
      if( WSAStartup ( MAKEWORD(
2, 2 ), & wsaData )
!= 0 )
[align=left]     {[/align]
[align=left]           cout<<"WSAStartup 无法初始化 !" <<endl ;[/align]
[align=left]           return MAIN_RETURN_ERROR ;[/align]
[align=left]     }[/align]
[align=left]
[/align]
      socketfd= socket ( AF_INET, SOCK_STREAM,
0 );
[align=left]      WSAAsyncSelect( socketfd , Window, WM_SOCKET, FD_ACCEPT );[/align]
[align=left]
[/align]
[align=left]      struct sockaddr_in my_addr;[/align]
      my_addr.sin_family  
= AF_INET;
      my_addr.sin_port    
= htons(
9990 );   // 服务器端口号
[align=left]      my_addr.sin_addr .S_un. S_addr = htonl ( INADDR_ANY );[/align]
[align=left]
[/align]
[align=left]      // 绑定[/align]
[align=left]      int    retVal ;[/align]
      retVal = bind ( socketfd,
( const struct sockaddr *)&my_addr , sizeof( struct sockaddr_in )
);
[align=left]      if( SOCKET_ERROR == retVal )[/align]
[align=left]     {[/align]
           cout<<"bind
failed !" <<"  
Reson: "<< WSAGetLastError()<<endl ;
[align=left]           closesocket( socketfd );[/align]
[align=left]           WSACleanup();[/align]
[align=left]           return -1;[/align]
[align=left]     }[/align]
[align=left]
[/align]
[align=left]      // 监听[/align]
[align=left]      retVal = listen ( socketfd, BACKLOG );[/align]
[align=left]      if( SOCKET_ERROR == retVal )[/align]
[align=left]     {[/align]
           cout<<"listen
failed !" <<"
Reson:"<< WSAGetLastError()<<endl ;
[align=left]           closesocket( socketfd );[/align]
[align=left]           WSACleanup();[/align]
[align=left]           return -1;[/align]
[align=left]     }[/align]
[align=left]
[/align]
      while( Ret = GetMessage(
& msg, NULL ,
0, 0 ) )
[align=left]     {[/align]
           if( Ret ==
-1 )
[align=left]          {[/align]
               cout<<"GetMessage
failed with error at "<< GetLastError()<<endl ;
[align=left]               return 0;[/align]
[align=left]          }[/align]
[align=left]
[/align]
           TranslateMessage(
&msg );
           DispatchMessage(
&msg );
[align=left]     }[/align]
[align=left]
[/align]
[align=left]      system("pause" );[/align]
[align=left]      return 0;[/align]
[align=left]}[/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: