晓凡的天梯
用UDP实现IPv4 IPv6两路消息接收
1
#define
SOCK_V4 1
//
2
#define
SOCK_V6 2
3
#define
IN6ADDR_ANY {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
4
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
}
5
#define
BUFFERSIZE 1500
6
typedef unsigned
char
u8;
7
typedef
int
u32;
8
typedef unsigned
int
s32;
9
10
typedef
struct
sockParam
{
11
struct
sockaddr
*
pSocket;
12
u32 addr_len;
13
s32 sockId;
14
sockParam()
15
{
16
pSocket
=
NULL;
17
addr_len
=
0
;
18
sockId
=
-
1
;
19
}
20
}
TSockParam;
21
struct
sockParam remoteSock[
2
];
22
void
SelectFd(u8
*
pRecvBuffer, u32
&
realLen,
struct
sockParam
*
psockParam,u8 sockNum);
23
void
DealBuffer(u8
*
pRecvBuffer, u32 realLen);
24
25
void
UDPRecvThread(u8 sockMask)
26
{
27
struct
sockParam socketArr[
2
];
28
struct
sockaddr_in sockv4,remotesockv4;
29
struct
sockaddr_in6 sockv6,remotesockv6;
30
u8 recvBuffer[BUFFERSIZE];
31
32
memset(recvBuffer,
0
,
sizeof
(recvBuffer));
33
if
(sockMask
&
SOCK_V4)
34
{
35
sockv4.sin_family
=
AF_INET;
36
sockv4.sin_port
=
htons(
5060
);
37
sockv4.sin_addr
=
htonl(INADDR_ANY);
//
指定为任意网络接口
38
socketArr[
0
].pSocket
=
(
struct
sockaddr
*
)
&
sockv4;
39
socketArr[
0
].addr_len
=
sizeof
(
struct
sockaddr_in);
40
remoteSock[
0
].pSocket
=
(
struct
sockaddr
*
)
&
remotesockv4;
41
remoteSock[
0
].addr_len
=
sizeof
(
struct
sockaddr_in);
42
}
43
if
(sockMask
&
SOCK_V6)
44
{
45
sockv6.sin_family
=
AF_INET6;
46
sockv6.sin_port
=
htons(
5060
);
47
sockv6.sin_addr
=
IN6ADDR_ANY;
48
socketArr[
1
].pSocket
=
(
struct
sockaddr
*
)
&
sockv6;
49
socketArr[
1
].addr_len
=
sizeof
(
struct
sockaddr_in6);
50
remoteSock[
1
].pSocket
=
(
struct
sockaddr
*
)
&
remotesockv6;
51
remoteSock[
1
].addr_len
=
sizeof
(
struct
sockaddr_in6);
52
}
53
//
创建socket
54
for
(u8 i
=
0
; i
<
2
; i
++
)
55
{
56
if
(NULL
==
socketArr[i].pSocket)
57
continue
;
58
socketArr[i].sockId
=
socket(socketArr[i].pSocket
->
sin_family,SOCK_DGRAM,
0
);
59
if
(socketArr[i].sockId
>=
0
)
60
{
61
//
非阻塞
62
fcntl(socketArr[i].sockId,F_SETFL,O_NONBLOCK);
63
if
(bind(socketArr[i].sockId,socketArr[i].pSocket,socketArr[i].addr_len)
<
0
)
64
{
65
printf(
"
bind error\n
"
);
66
}
67
}
68
else
69
{
70
printf(
"
socket create error\n
"
);
71
}
72
}
73
74
while
(
1
)
75
{
76
u32 dwLen
=
BUFFERSIZE;
77
//
接收消息
78
SelectFd(recvBuffer,dwLen,socketArr,
2
);
79
DealBuffer(recvBuffer,dwLen);
80
}
81
printf(
"
exit\n
"
)
82
}
83
84
85
void
SelectFd(u8
*
pRecvBuffer, u32
&
realLen,
struct
sockParam
*
psockParam,u8 sockNum)
86
{
87
fd_set sockSet;
88
s32 fdMax
=
0
;
89
memset(pRecvBuffer,
0
, realLen);
90
FD_ZERO(sockSet);
91
if
(remoteSock)
92
for
(u8 i
=
0
; i
<
sockNum; i
++
)
93
{
94
if
(psockParam[i].sockId
<
0
)
95
continue
;
96
FD_SET(psockParam[i].sockId, sockSet);
97
if
(psockParam[i].sockId
>
fdMax)
98
{
99
fdMax
=
psockParam[i].sockId;
100
}
101
}
102
if
(select(fdMax
+
1
,
&
sockSet,NULL,NULL,
0
)
>
0
)
103
{
104
for
(u8 i
=
0
; i
<
sockNum; i
++
)
105
{
106
if
(psockParam[i].sockId
<
0
)
107
continue
;
108
if
(FD_ISSET(psockParam[i].sockId,
&
sockSet))
109
{
110
realLen
=
recvfrom(psockParam[i].sockId,pRecvBuffer,realLen
-
1
,
0
,
111
remoteSock[i].pSocket,
&
remoteSock[i].addr_len);
112
}
113
114
}
115
}
116
}
117
void
DealBuffer(u8
*
pRecvBuffer,u32 realLen)
118
{
119
//
一般让另一个线程去处理数据,并应答
120
}
posted on 2008-11-16 10:58
晓凡
阅读(610)
评论(0)
编辑
收藏
引用
只有注册用户
登录
后才能发表评论。
网站导航:
博客园
博客园最新博文
博问
管理
Powered by:
C++博客
Copyright © 晓凡
<
2008年11月
>
日
一
二
三
四
五
六
26
27
28
29
30
31
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
1
2
3
4
5
6
导航
C++博客
首页
新随笔
联系
聚合
管理
统计
随笔 - 1
文章 - 0
评论 - 0
引用 - 0
常用链接
我的随笔
我的评论
我参与的随笔
留言簿
(1)
给我留言
查看公开留言
查看私人留言
随笔档案
2008年11月 (1)
搜索
最新评论