#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;
}