udp 传输总结

udp信息传递的方式分为三种

1 单播 客户端与服务器之间的点对点连接

2 广播 主机之间 1对所有的通讯模式 ()

3组播  主机之间1对1组的通讯模式    (局域网)

主要使用的是udp组播  和单播

        然而在ip组播环中,数据包的目的地址不是一个,而是一组,形成组地址。所有的信息接收者都加入到一个组内,并且一旦加入之后,流向组地址的数据立即开始向接收者传输,组中的所有成员都能接收到数据包。组播组中的成员是动态的,主机可以在任何时刻加入和离开组播组。

        组播组可以是永久的也可以是临时的。组播组地址中,有一部分由官方分配的,称为永久组播组。永久组播组保持不变的是它的ip地址,组中的成员构成可以发生变化。永久组播组中成员的数量都可以是任意的,甚至可以为零。那些没有保留下来供永久组播组使用的ip组播地址,可以被临时组播组利用。

udp组播的基本步骤   1.建立socket 2.socket和端口绑定 3.加入一个组播组 4.通过sendto进行数据的收发 5.关闭socket

发送数据包  入口参数  服务器地址  端口号  消息体

static void send(String ServerIp, int Port, String Msg) {

  udpSocket.beginPacket(ServerIp.c_str(), Port);//开始数据包

  udpSocket.write(WIFI_MSG_FH);//写高八位

  udpSocket.print(Msg);

  udpSocket.write(WIFI_MSG_FT);//写第八位

  udpSocket.endPacket();//结束数据包

}

 udpSocket.beginPacket(ServerIp.c_str(), Port);//开始数据包

 udpSocket.endPacket();//结束数据包

  send(udpSocket.remoteIP().toString(), udpSocket.remotePort(), sendMsg);//发送远程数据包

ip  地址    端口号  和信息

一般发送远程数据包的时候需要把数据处理好之后sendmsg 再进行传输

static void detectValidMsgFromServer() //检测来自服务器的有效消息

和检测muc的逻辑大致一样

 udpSocket.beginMulticast(IPAddress(MULTICAST_ADDR), UDP_LOCAL_PORT);

//开始组播

透传指令   app和主机之间的通讯  esp32作为一个转发者  

void wifi_app_replay(String token, String msg)

{ wifi_remote_sendMsg(token, msg, String(reciveFrameNum), reciveUUUID); }

首先我们看下发送方:

      1)构造socket

       udp_socket = socket(AF_INET, SOCK_DGRAM, 0);

       //如果需要绑定,记得绑定本地地址

      2)指定发送的组播地址和端口

    struct sockaddr_in mcast_addr; 
    memset(&mcast_addr, 0, sizeof(mcast_addr));
    mcast_addr.sin_family = AF_INET;
    mcast_addr.sin_addr.s_addr = inet_addr(mcast_ip.c_str());
    mcast_addr.sin_port = htons(mcast_port); 

      3)发送组播数据

      //it为组播数据内容描述

       int n = sendto(udp_socket, it.c_str(), it.length(),0,(struct sockaddr*)&mcast_addr,sizeof(mcast_addr));

      4)关闭socket

       close(udp_socket);

下面看看接收方的实现

1)同样是先构建socket

udp_socket = socket(AF_INET, SOCK_DGRAM, 0);

2)绑定本机地址

   //
    struct sockaddr_in local_addr;
    memset(&local_addr, 0, sizeof(local_addr));
    local_addr.sin_family = AF_INET;
    local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    //local_addr.sin_addr.s_addr = inet_addr(local_ip.c_str());//指定发送的网口
    local_addr.sin_port = htons(mcast_port);
    //建立本地捆绑(主机地址/端口号)
    int err = -1;
    err = bind(udp_socket,(struct sockaddr*)&local_addr, sizeof(local_addr));

3)加入组播,才能接收到组播信息
    struct ip_mreq mreq;
    mreq.imr_multiaddr.s_addr = inet_addr(mcast_ip.c_str());
    if(local_ip.empty()){
        mreq.imr_interface.s_addr = htonl(INADDR_ANY);                //任意接口接收组播信息
    }else{
        mreq.imr_interface.s_addr = inet_addr(local_ip.c_str());    //指定接口接收组播信息
    }

   err = setsockopt(udp_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));

4)接收数据

   sockaddr_in srv_Addr;//用于存储发送方信息
   socklen_t addr_len = sizeof(srv_Addr);
   char *buff = new char[buf_size];

   memset(buff, 0, buf_size);
   n = recvfrom(udp_socket, buff, buf_size, 0,(struct sockaddr*)&srv_Addr,&addr_len);
 

工程中的整体逻辑‘  创建socket  绑定本地端口号 ip    然后加入组播组   检测数据包 数据写在buf中  发送指定的ip 端口号

也可以使用asyncudpclient库 进行传输

有组播  广播  单播的形式   引入了AsyncUDPPacket    异步udp数据包 发送或者接受数据

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值