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