#include
"stdafx.h"
#include
<winsock2.h>
#include
<iostream>
#pragma
comment
(
lib
,
"ws2_32.lib"
)
using
namespace
std
;
#define
MSGSIZE
1024
SOCKET
g_sNewClientConnection
;
BOOL
g_bNewConnectionArrived
=
FALSE
;
struct
PER_IO_OPERATION_DATA
{
WSAOVERLAPPED
overlap
;
//
重叠结构体
WSABUF
Buffer
;
//
缓冲对象
char
szMessage
[
MSGSIZE
];
//
缓冲区字符对象
DWORD
NumberOfBytesRecvd
;
//
接受字节位
DWORD
Flags
;
//
标识位
SOCKET
sClient
;
// Socket
};
typedef
PER_IO_OPERATION_DATA
*
LPPER_IO_OPERATION_DATA
;
enum
{
MAIN_RETURN_ERROR
= -1,
MAIN_RETURN_NORMAL
= 0,
};
void
CALLBACK
CompletionROUTINE
(
DWORD
dwError
,
DWORD
cbTransferred
,
LPWSAOVERLAPPED
lpOverlapped
,
DWORD
dwFlags
)
{
LPPER_IO_OPERATION_DATA
lpPerIOData
= (
LPPER_IO_OPERATION_DATA
)
lpOverlapped
;
if
(
dwError
!= 0 ||
cbTransferred
== 0 )
{
closesocket
(
lpPerIOData
->
sClient
);
HeapFree
(
GetProcessHeap
(), 0,
lpPerIOData
);
}
else
{
lpPerIOData
->
szMessage
[
cbTransferred
] =
'\0'
;
//
向客户端发送数据
send
(
lpPerIOData
->
sClient
,
lpPerIOData
->
szMessage
,
cbTransferred
, 0 );
memset
( &
lpPerIOData
->
overlap
, 0,
sizeof
(
WSAOVERLAPPED
) );
lpPerIOData
->
Buffer
.
len
=
MSGSIZE
;
lpPerIOData
->
Buffer
.
buf
=
lpPerIOData
->
szMessage
;
WSARecv
(
lpPerIOData
->
sClient
, &
lpPerIOData
->
Buffer
, 1, &
lpPerIOData
->
NumberOfBytesRecvd
,
&
lpPerIOData
->
Flags
, &
lpPerIOData
->
overlap
,
CompletionROUTINE
);
cout
<<
lpPerIOData
->
Buffer
.
buf
<<
endl
;
}
}
DWORD
WINAPI
WorkThread
(
LPVOID
lpParam
)
{
LPPER_IO_OPERATION_DATA
lpPerIOData
=
NULL
;
while
(
TRUE
)
{
if
(
g_bNewConnectionArrived
)
//
如果有新的请求
{
lpPerIOData
= (
LPPER_IO_OPERATION_DATA
)
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
PER_IO_OPERATION_DATA
) );
lpPerIOData
->
Buffer
.
len
=
MSGSIZE
;
lpPerIOData
->
Buffer
.
buf
=
lpPerIOData
->
szMessage
;
lpPerIOData
->
sClient
=
g_sNewClientConnection
;
WSARecv
(
lpPerIOData
->
sClient
, &
lpPerIOData
->
Buffer
, 1, &
lpPerIOData
->
NumberOfBytesRecvd
,
&
lpPerIOData
->
Flags
, &
lpPerIOData
->
overlap
,
CompletionROUTINE
);
g_bNewConnectionArrived
=
FALSE
;
cout
<<
lpPerIOData
->
Buffer
.
buf
<<
endl
;
}
SleepEx
( 1000,
TRUE
);
}
return
0;
}
int
_tmain
(
int
argc
,
_TCHAR
*
argv
[])
{
//
初始化
Winsock 2.2
WSADATA
wsaData
;
if
(
WSAStartup
(
MAKEWORD
( 2, 2 ), &
wsaData
) != 0 )
{
cout
<<
"WSAStartup
无法初始化
!"
<<
endl
;
return
MAIN_RETURN_ERROR
;
}
SOCKET
ListenSocket
;
ListenSocket
=
WSASocket
(
AF_INET
,
SOCK_STREAM
, 0,
NULL
, 0,
WSA_FLAG_OVERLAPPED
);
if
(
INVALID_SOCKET
==
ListenSocket
)
{
cout
<<
"Socket Failed !"
<<
" Reson:"
<<
WSAGetLastError
()<<
endl
;
WSACleanup
();
return
MAIN_RETURN_ERROR
;
}
//
设置服务器
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
, 3 );
if
(
SOCKET_ERROR
==
retVal
)
{
cout
<<
"listen failed !"
<<
" Reson:"
<<
WSAGetLastError
()<<
endl
;
closesocket
(
ListenSocket
);
WSACleanup
();
return
-1;
}
DWORD
dwThreadId
;
CreateThread
(
NULL
, 0,
WorkThread
,
NULL
, 0, &
dwThreadId
);
//
循环接受客户端请求
sockaddr_in
addrClient
;
int
addrClientLen
=
sizeof
(
addrClient
);
while
(
TRUE
)
{
g_sNewClientConnection
=
accept
(
ListenSocket
, (
struct
sockaddr
*)&
addrClient
, &
addrClientLen
);
g_bNewConnectionArrived
=
TRUE
;
cout
<<
"Accept Client: "
<<
inet_ntoa
(
addrClient
.
sin_addr
)<<
" : "
<<
ntohs
(
addrClient
.
sin_port
)<<
endl
;
}
closesocket
(
ListenSocket
);
closesocket
(
g_sNewClientConnection
);
system
(
"pause"
);
return
0;
}