用udp协议通讯示例 UDP实现广播接收回复的例子

一、绪言

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主要代码:

view source  print ?
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,(structsockaddr*)&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,(structsockaddr*)&from,fromlen);
24.   
25.         }
26.         Sleep(500);
27.     }
28.     closesocket(socket1);
29. }

udpcilent主要代码:

view source  print ?
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,(structsockaddr*)&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简单了很多,在数据可靠性不是很高的情况下,有使用的价值。

 

 

 

两段网上抄的例子, 再加上一些特别的回复. 主要用于自动查找服务器, 方便DEBUG的.
流程是由客户端进行广播, 服务器收到广播后回复自己的IP给客户端, 实现客户端自动查找服务器使用的. 之前发的测试程序被抱怨要慢慢输入服务器IP, 现在搞个自动查找的, 不过没搞完....

客户端

C/C++ code ? ?
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
// UDPBroadcastSend.cpp : Defines the entry point for the console application.
//
  
#include "stdafx.h"
#include  
#include 
#include  
#include  
#pragma comment(lib,"ws2_32.lib")  
  
using  namespace  std;
  
int  _tmain( int  argc, _TCHAR* argv[])
{  
     SOCKET sock;  
     sockaddr_in addrto;  
     WSADATA wsdata;  
     bool  bsocket;  
     char  smsg[100] = {0};
     cout<< "input what message to send\n:" <
     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 *)&opt, sizeof (opt));  
     int  nlen= sizeof (addrto);  
     char  buf[100] = {0};
     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) + 1,0,(sockaddr*)&addrto,nlen);  
         if (ret==SOCKET_ERROR)  
         {  
             printf ( "%d/n" ,WSAGetLastError());  
         }  
         else  
         {         
             printf ( "It'sock OK.\n" );  
         }  
  
         ret = recvfrom( sock, buf,  sizeof (buf), 0, (sockaddr*)&addrto, &nlen );
         if  (SOCKET_ERROR == ret)
         {
             printf ( "error on recv after send!\n" );
         }
         else
         {
             printf ( "recv after send: %s\n" , buf);
         }
     }  
     return  0;  
}  


服务器端:
C/C++ code ? ?
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
// UDPBroadcastRecv.cpp : Defines the entry point for the console application.
//
  
#include "stdafx.h"
#include  
#include  
#include  
#pragma comment(lib,"ws2_32.lib")  
  
int  _tmain( int  argc, _TCHAR* argv[])
{  
     SOCKET sock;  
     sockaddr_in from,a;  
     WSADATA wsdata;  
     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 *)&optval, sizeof (optval));  
     // 把该套接字绑定在一个具体的地址上  
     bind(sock,(sockaddr *)&a, sizeof (sockaddr_in));  
     char  buf[256];  
     while (1)  
     { //从广播地址接收消息,注意用来绑定的地址和接收消息的地址是不一样的  
         recvfrom(sock,buf,256,0,( struct  sockaddr FAR *)&from,( int  FAR *)&fromlength);  
         //Sleep(2000);  
         printf ( "%sock\n" ,buf);  
         sendto( sock, buf,  strlen (buf) + 1, 0, ( struct  sockaddr FAR *)&from, fromlength );
         ZeroMemory(buf,256);  
     }  
     return  0;
}

http://blog.sina.com.cn/s/blog_4fe4477501018697.html

你可能感兴趣的:(miscellaneous)