加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

用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简单了很多,在数据可靠性不是很高的情况下,有使用的价值。

 

 

 

两段网上抄的例子, 再加上一些特别的回复. 主要用于自动查找服务器, 方便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:"<<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 *)&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;
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有