用udp协议通讯示例 UDP实现广播接收回复的例子(转)
(2012-11-30 09:54:00)
标签:
杂谈 |
一、绪言
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; } |