一、绪言
udp是一种面向非连接,不可靠的通讯协议,相对于tcp来说,虽然可靠性不及,但传输效率较高。所以在网络上仍有很大的用途。这几日需要了解下udp通讯的过程,上网发现这方面的资料还挺少。于是仔细的翻找了下msdn,基本上搞清楚了udp通讯的过程。做了一个测试的例子。希望对大家有帮助。
二、udp的通讯过程
server端: open a socket(socket)--->name the socket(bind)--->send and receive data(sendto recvfrom)--->close socket(closesocket)
client端: open a socket(socket)---------------------------->send and receive data(sendto recvfrom)--->close socket(closesocket)
server端无需listen,client端无需connect,因此udp中server和client的区别相对较模糊。只要调用sendto和recvfrom就可以给指定的地址收发数据,但并不保证收发的数据的完整性和可靠性。
三、示例
udpserver主要代码:
01.
void
main()
02.
{
03.
SOCKET socket1;
04.
05.
InitWinsock();
06.
struct
sockaddr_in local;
07.
struct
sockaddr_in from;
08.
int
fromlen =
sizeof
(from);
09.
local.sin_family=AF_INET;
10.
local.sin_port=htons(1000);
///监听端口
11.
local.sin_addr.s_addr=INADDR_ANY;
///本机
12.
13.
socket1=socket(AF_INET,SOCK_DGRAM,0);
14.
bind(socket1,(
struct
sockaddr*)&local,
sizeof
local);
15.
while
(1)
16.
{
17.
char
buffer[1024]=
"\0"
;
18.
printf
(
"waiting for message from others-------------\n"
);
19.
if
(recvfrom(socket1,buffer,
sizeof
buffer,0,(
struct
sockaddr*)&from,&fromlen)!=SOCKET_ERROR)
20.
{
21.
printf
(
"Received datagram from %s--%s\n"
,inet_ntoa(from.sin_addr),buffer);
22.
给cilent发信息
23.
sendto(socket1,buffer,
sizeof
buffer,0,(
struct
sockaddr*)&from,fromlen);
24.
25.
}
26.
Sleep(500);
27.
}
28.
closesocket(socket1);
29.
}
udpcilent主要代码:
01.
void
main()
02.
{
03.
SOCKET socket1;
04.
05.
InitWinsock();
06.
struct
sockaddr_in server;
07.
int
len =
sizeof
(server);
08.
server.sin_family=AF_INET;
09.
server.sin_port=htons(1000);
///server的监听端口
10.
server.sin_addr.s_addr=inet_addr(
"168.168.0.10"
);
///server的地址
11.
12.
socket1=socket(AF_INET,SOCK_DGRAM,0);
13.
while
(1)
14.
{
15.
char
buffer[1024]=
"\0"
;
16.
printf
(
"input message\n"
);
17.
scanf
(
"%s"
,buffer);
18.
if
(
strcmp
(buffer,
"bye"
)==0)
19.
break
;
20.
if
(sendto(socket1,buffer,
sizeof
buffer,0,(
struct
sockaddr*)&server,len)!=SOCKET_ERROR)
21.
{
22.
if
(recvfrom(socket1,
23.
buffer,
24.
sizeof
buffer,
25.
0,
26.
(
struct
sockaddr*)&server,&len) != SOCKET_ERROR)
27.
printf
(
"rece from server:%s\n"
,buffer);
28.
}
29.
}
30.
closesocket(socket1);
31.
}
四、结束语
udp通讯比tcp简单了很多,在数据可靠性不是很高的情况下,有使用的价值。
两段网上抄的例子,
流程是由客户端进行广播,
客户端
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
|
//
//
#include
#include
#include
#include
#include
#pragma
using
namespace
std;
int
_tmain(
int
argc,
{
SOCKET
sockaddr_in
WSADATA
bool
bsocket;
char
smsg[100]
cout<<
"input
<<endl;
cin>>smsg;
//启动SOCKET库,版本为2.0
WSAStartup(0x0202,&wsdata);
sock=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,WSA_FLAG_OVERLAPPED);
bsocket=
true
;
//然后赋值给地址,用来从网络上的广播地址接收消息;
addrto.sin_family=AF_INET;
addrto.sin_addr.s_addr=INADDR_BROADCAST;
addrto.sin_port=htons(9000);
bool
opt=
true
;
//设置该套接字为广播类型,
setsockopt(sock,SOL_SOCKET,SO_BROADCAST,(
char
FAR
sizeof
(opt));
int
nlen=
sizeof
(addrto);
char
buf[100]
while
(1)
{
addrto.sin_family=AF_INET;
addrto.sin_addr.s_addr=INADDR_BROADCAST;
addrto.sin_port=htons(9000);
Sleep(1000);
//从广播地址发送消息
int
ret=sendto(sock,smsg,
strlen
(smsg)
if
(ret==SOCKET_ERROR)
{
printf
(
"%d/n"
,WSAGetLastError());
}
else
{
printf
(
"It'sock
);
}
ret
sizeof
(buf),
if
(SOCKET_ERROR
{
printf
(
"error
);
}
else
{
printf
(
"recv
,
}
}
return
0;
}
|
服务器端:
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
|
//
//
#include
#include
#include
#include
#pragma
int
_tmain(
int
argc,
{
SOCKET
sockaddr_in
WSADATA
bool
optval;
//启动SOCKET库,版本为2.0
WSAStartup(0x0202,&wsdata);
optval=
true
;
//然后赋值给两个地址,一个用来绑定套接字,一个用来从网络上的广播地址接收消息;
a.sin_family=AF_INET;
a.sin_addr.s_addr=INADDR_ANY;
a.sin_port=htons(9000);
from.sin_family=AF_INET;
from.sin_addr.s_addr=INADDR_BROADCAST;
from.sin_port=htons(5050);
int
fromlength=
sizeof
(SOCKADDR);
//用UDP初始化套接字
sock=socket(AF_INET,SOCK_DGRAM,0);
//
setsockopt(sock,SOL_SOCKET,SO_BROADCAST,(
char
FAR
sizeof
(optval));
//
bind(sock,(sockaddr
sizeof
(sockaddr_in));
char
buf[256];
while
(1)
{
//从广播地址接收消息,注意用来绑定的地址和接收消息的地址是不一样的
recvfrom(sock,buf,256,0,(
struct
sockaddr
int
FAR
//Sleep(2000);
printf
(
"%sock\n"
,buf);
sendto(
strlen
(buf)
struct
sockaddr
ZeroMemory(buf,256);
}
return
0;
}
http://blog.sina.com.cn/s/blog_4fe4477501018697.html
|