UDP组播的c++实现

1 写socket的时候UDP和TCP的代码区别就是 是否有连接过程;有connect连接的代码的就是TCP,没有连接的就是UDP

以下代码是发送信息给组播地址(没有写接收代码。接收的代码就是要写个加入多播组,从多播组接收的逻辑)

参考:https://blog.csdn.net/zhizhengguan/article/details/109312144

// UDP_socket.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <stdio.h>
#include <stdlib.h>

#if defined(_WIN32)
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#pragma comment (lib, "Ws2_32.lib")
#pragma comment(lib,"Iphlpapi.lib")
#else
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#endif // defined(_WIN32)

int main() {
    char group_addr[16] = "224.1.3.250";



    //初始化WinSock.否则socket(AF_INET, SOCK_DGRAM, 0)会一直返回-1

    WSADATA WSAData;

    if (WSAStartup(MAKEWORD(2, 0), &WSAData) != 0)

    {

        return FALSE;

    }

    int socked = ::socket(AF_INET, SOCK_DGRAM, 0);
    if (socked < 0)
    {
        perror("socket failed!");
        return 2;
    }

    struct sockaddr_in remote_addr;
    memset(&remote_addr, 0, sizeof(remote_addr));

    remote_addr.sin_family = AF_INET;
    inet_pton(AF_INET, group_addr, &remote_addr.sin_addr.s_addr);
    remote_addr.sin_port = htons(25666);

    char buf[200] = "1234567890";
    int length = 0;
    int i = 0;
    while (1)
    {
        i++;

        length = sendto(socked, buf, strlen(buf), 0, (struct sockaddr*)&remote_addr, sizeof(remote_addr));
        printf("Send Message%s,%d\n", buf,i);
    }
    closesocket(socked);
    return 0;
}

 

 


 

从多播组上拉流,要记得先加入多播组:

// UDP_socket.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <stdio.h>
#include <stdlib.h>

#if defined(_WIN32)
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#pragma comment (lib, "Ws2_32.lib")
#pragma comment(lib,"Iphlpapi.lib")
#else
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#endif // defined(_WIN32)



int main(int argc, char* argv[]) {
    WSADATA WSAData;

    if (WSAStartup(MAKEWORD(2, 0), &WSAData) != 0)

    {

        return FALSE;

    }
    int socked = socket(AF_INET, SOCK_DGRAM, 0);
    if (socked < 0)
    {
        perror("socket failed!");
        return 2;
    }

    char group[16] = "224.1.2.3";

    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_port = htons(20123);

    int ret = bind(socked, (struct sockaddr*)&local_addr, sizeof(local_addr));
    if (ret < 0)
    {
        perror("bind failed !");
        return 3;
    }


    struct ip_mreq mreq;
    inet_pton(AF_INET,group, &mreq.imr_multiaddr.s_addr);
    mreq.imr_interface.s_addr = htonl(INADDR_ANY);

    /*
     *
     *  int setsockopt(int sockfd, int level, int optname,
                      const void *optval, socklen_t optlen);
     * param:
     *      optname
     *          * IP_MULTICAST_LOOP 支持多播数据回送
     *          * IP_ADD_MEMBERSHIP 加入多播组
     *          * IP_DROP_MEMBERSHIP 离开多播组
     *      optval
     *          * IP_MULTICAST_LOOP 选项对应传入 unsigned int 来确认是否支持多播数据回送
     *          * IP_ADD_MEMBERSHIP 传入 ip_mreq
     *          * IP_DROP_MEMBERSHIP 传入 ip_mreq
     *
     * */
    ret = setsockopt(socked, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&mreq, sizeof(mreq));
    if (ret < 0) {
        perror("setsockopt failed !");
        return 3;
    }
    else
    {
        printf("setsockopt success\n");
    }


    char buf[10240];
    int length = 0;
    struct sockaddr_in sender;
    socklen_t sender_len = sizeof(sender);
    while (true) {
        memset(buf, 0, sizeof(buf));
        length = recvfrom(socked, buf, sizeof(buf), 0, (struct sockaddr*)&sender, &sender_len);
        buf[length] = '\0';
        printf("%s\n", buf);
    }
    setsockopt(socked, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const char*) & mreq, sizeof(mreq));
    closesocket(socked);
    return 0;
}

 


 

UDP单播的接收

源码:https://blog.csdn.net/ljjjjjjjjjjj/article/details/118944294

#include <stdio.h>
#include <stdlib.h>

#if defined(_WIN32)
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#pragma comment (lib, "Ws2_32.lib")
#pragma comment(lib,"Iphlpapi.lib")

#else
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#endif // defined(_WIN32)



    int main(void)
    {
        
        WSADATA wsd;    // 初始化Socket的变量
        SOCKET s;        // 用于通信的Socket句柄
        SOCKADDR_IN sRecvAddr, sSendAddr;    // 分别为接收地址和发送地址
        USHORT uPort = 14555;                // 通信端口
        CHAR szBuf[4096] = { 0 };            // 通信数据缓冲区
        int nBufLen = 4096, nResult = 0, nSenderAddrSize = sizeof(sSendAddr);

        // 初始化Socket2.2版本
        nResult = WSAStartup(MAKEWORD(2, 2), &wsd);
        if (nResult != NO_ERROR)
        {
            printf("WSAStartup failed:%d\n", WSAGetLastError());
            return 1;
        }

        // 创建一个Socket,SOCK_DGRAM表示UDP类型
        s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if (s == INVALID_SOCKET)
        {
            printf("socket failed:%d\n", WSAGetLastError());
            return 1;
        }

        // 填充Socket接口
        sRecvAddr.sin_family = AF_INET;        // 地址协议,AF_INET支持TCP和UDP
        sRecvAddr.sin_port = htons(uPort);    // 通信端口,htons转为网络字节顺序
        //INADDR_ANY转换过来就是0.0.0.0,泛指本机的意思,也就是表示本机的所有IP
        sRecvAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);    // 接收任意地址数据

        // 绑定Socket至本机
        nResult = bind(s, (SOCKADDR*)&sRecvAddr, sizeof(sRecvAddr));
        if (nResult != 0)
        {
            printf("bind failed:%d\n", WSAGetLastError());
            return 1;
        }

        printf("Waiting recv data...\n");

        while (1)
        {
            // 阻塞式接收数据
            nResult = recvfrom(s, szBuf, nBufLen, 0, (SOCKADDR*)&sSendAddr, &nSenderAddrSize);
            if (nResult == SOCKET_ERROR)
            {
                printf("recvfrom failed:%d\n", WSAGetLastError());
            }
            else
            {
                //printf("SenderIP  :%s\n", inet_ntoa(sSendAddr.sin_addr));
                printf("SenderData:%d\n", nResult);
            }
        }
        // 关闭Socket连接
        nResult = closesocket(s);
        if (nResult == SOCKET_ERROR)
        {
            printf("closesocket failed:%d\n", WSAGetLastError());
            return 1;
        }
        // 清理Socket
        WSACleanup();

        system("pause");
        return 0;
    }

 

posted on 2023-05-08 18:27  邗影  阅读(731)  评论(0编辑  收藏  举报

导航