1
2
3
4
5
6
7
|
#define MYWSA_PACKSIZE 8192 //网络数据包完整字节数
#define MYWSA_HEADSIZE sizeof(int) * 2 //包头字节数
#define MYWSA_BUFSIZE MYWSA_PACKSIZE - MYWSA_HEADSIZE //网络数据包缓冲区字节数
#define MYWSA_SACCEPT 12013 //(LPARAM消息)服务端接收到客户端的连接
#define MYWSA_SLOST 12014 //(LPARAM消息)服务端失去与客户端的连接
#define MYWSA_SRECEIVE 12015 //(LPARAM消息)服务端接收到客户端的数据
|
1
2
3
4
5
6
|
struct
myWSAPack
//标准数据包结构
{
int
WSALen;
//数据包长度
int
WSAId;
//数据包ID
char
Buffer[MYWSA_BUFSIZE];
//数据包内容
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
LRESULT
myWSAServer::OnReceive(
WPARAM
wParam,
LPARAM
lParam)
{
switch
(WSAGETSELECTEVENT(lParam))
{
case
FD_READ:
{
memset
(m_Buffer, 0,
sizeof
(m_Buffer));
//TCP是流数据,发送方在连续发送时有可能集在一起发(粘包)
int
Lenth = ::recv((SOCKET)wParam, m_Buffer,
sizeof
(m_Buffer), 0);
UnPack((SOCKET)wParam, m_Buffer, Lenth);
}
break
;
case
FD_CLOSE:
{
myWSAEmpty data = {0};
bool
Found =
false
;
for
(myCliIt it = m_ClientQueue.begin(); it != m_ClientQueue.end(); ++ it)
{
if
((*it).sClient == (SOCKET)wParam)
{
Found =
true
;
closesocket((*it).sClient);
//销毁该SOCKET号的资源
sprintf_s(data.Addr,
sizeof
(data.Addr),
"%s"
, (*it).Addr);
m_ClientQueue.erase(it);
break
;
}
}
if
(
true
== Found)
{
m_ClosedQue.push(data);
//投递消息,通知外部程序该客户端已关闭
::PostMessage(m_MainHandle, m_MSGID, m_WPID, MYWSA_SLOST);
}
}
break
;
}
return
1;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
int
myWSAServer::UnPack(SOCKET sClient,
char
*Buffer,
int
Lenth)
{
if
(Lenth <= 0 || NULL == Buffer)
{
return
-1;
}
int
Len = Lenth;
char
*lpHead = Buffer;
myWSAPack *lpPack = (myWSAPack*)lpHead;
while
(Len > 0)
{
if
(lpPack->WSALen <= 0 || lpPack->WSALen > MYWSA_PACKSIZE)
{
sprintf_s(m_Log,
sizeof
(m_Log),
"拆包出错:WSALen=%d"
, lpPack->WSALen);
Log(m_Log);
return
-1;
}
if
(Len < lpPack->WSALen)
{
sprintf_s(m_Log,
sizeof
(m_Log),
"拆包出错:len=%d != lPHead->WSALen=%d"
, Len, lpPack->WSALen);
Log(m_Log);
return
-1;
}
//尝试剥离出一个数据包
myWSASDATA data = {0};
data.Lenth = lpPack->WSALen;
memcpy
(data.Buffer, lpPack, lpPack->WSALen);
//剩下的未处理数据块指针和长度
Len -= lpPack->WSALen;
lpHead = lpHead + lpPack->WSALen;
lpPack = (myWSAPack*)lpHead;
bool
Found =
false
;
myWSAPack *Pack = (myWSAPack*)data.Buffer;
for
(myCliIt it = m_ClientQueue.begin(); it != m_ClientQueue.end(); ++ it)
{
if
((*it).sClient == sClient)
{
if
(
true
== m_IsHearting && MYWSA_HEARTID == Pack->WSAId)
//心跳包
{
memset
((*it).Heart, 0,
sizeof
((*it).Heart));
//消除该客户端心跳记录,证明它已回应过
}
else
//数据包
{
sprintf_s(data.Addr,
sizeof
(data.Addr),
"%s"
, (*it).Addr);
Found =
true
;
}
break
;
}
}
if
(
false
== Found)
{
continue
;
}
m_ReceiveQue.push(data);
::PostMessage(m_MainHandle, m_MSGID, m_WPID, MYWSA_SRECEIVE);
}
return
1;
}
|