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