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]
[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]
相关文章推荐
- Windows平台下 WSAEventSelect模型 服务器
- 【服务器框架】(AsyncSelect模型、Windows平台)
- WSAAsyncSelect和windows客户端异步IO模型
- Windows平台下基于Select模型的服务器
- Windows操作系统I/O模型—笔记2(异步选择(WSAAsyncSelect)模型)
- WSAAsyncselect 模型中,服务器与客户端消息的收发
- 多种SOKECT通讯模型的理解(select,WSAAsyncSelect,WSAEventSelect,Overlapped I/O 事件通知,Overlapped I/O 完成例程,IOCP)
- 基于WSAEventSelect模型的服务器设计
- Winsock I/O模型之WSAAsyncSelect
- 深入理解WSAAsyncselect网络模型
- WSAEventSelect模型 ---应用实例,重写TCP服务器实例
- Windows套接字I/O模型(4) -- WSAEventSelect模型
- WSAAsyncSelect 模型 - 还是接着以前的socket、 部分继续研究, 近期将精力 放在各种模型上面,比较缺点,实现出来
- 套接字I/O模型之 消息机制-WSAAsyncSelect
- 套接字I/O模型-WSAAsyncSelect
- Windows套接字WSAAsyncSelect
- [置顶] WinSock 异步I/O模型[2]---异步选择 - WSAAsyncSelect
- WsaAsyncSelect编程模型
- 二、异步选择模型(WSAAsyncSelect)
- Winsock异步事件通知模型WSAAsyncSelect