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数据包 发送或者接受数据