Windows下实现UDP设备发现服务端

xingyun86 28天前 125

Windows下实现UDP设备发现服务端

static SOCKET create_server_socket_udp(void)
{
    SOCKET server_udp = INVALID_SOCKET;
    int i_sock_opt_true = 1;
    unsigned char uc_sock_opt_true = 1;
    unsigned long ul_sock_opt_true = 1ul;
    server_udp = socket(PF_INET, SOCK_DGRAM, 0);  
    //server_udp = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (server_udp == INVALID_SOCKET) 
    {
        printf("unable to create socket\n");
        return(INVALID_SOCKET);
    }
    // reuse socket addr
    if ((setsockopt(server_udp, SOL_SOCKET, SO_REUSEADDR, (void*)&i_sock_opt_true, sizeof(i_sock_opt_true))) == SOCKET_ERROR)
    {
        printf("setsockopt error(%d)\n", WSAGetLastError());
        return(INVALID_SOCKET);
    }
    if ((setsockopt(server_udp, IPPROTO_IP, IP_MULTICAST_LOOP, &uc_sock_opt_true, sizeof(uc_sock_opt_true))) == SOCKET_ERROR)
    {
        printf("setsockopt error(%d)\n", WSAGetLastError());
        return(INVALID_SOCKET);
    }
    struct ip_mreq mreq;
    mreq.imr_multiaddr.s_addr = inet_addr("239.255.255.250");
    mreq.imr_interface.s_addr = htonl(INADDR_ANY);
    if (setsockopt(server_udp, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == SOCKET_ERROR)
    {
        printf("memberchip error(%d)\n", WSAGetLastError());
        return(INVALID_SOCKET);
    }
    //if (ioctlsocket(server_udp, FIONBIO, (unsigned long*)&ul_sock_opt_true) == SOCKET_ERROR) 
    //{
    //    printf("ioctlsocket error(%d)\n", WSAGetLastError());
    //    return(INVALID_SOCKET);
    //}
    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(3702);
    if (bind(server_udp, (struct sockaddr*)&local_addr, sizeof(local_addr)) == SOCKET_ERROR)
    {
        printf("bind error(%d)\n", WSAGetLastError());
        return(INVALID_SOCKET);
    }
    return server_udp;
}
DWORD WINAPI DeviceDiscoveryServer(LPVOID lpv)
{
    int nNum = (*(int*)lpv);
    SOCKET server_udp = create_server_socket_udp();
    char* pData = (char*)malloc(10240);
    if (pData == NULL)
    {
        return(0);
    }
    while (1)
    {
        struct sockaddr to_addr = { 0 };
        int n_to_addr = sizeof(to_addr);
        int nRead = recvfrom(server_udp, pData, 10240, 0, &to_addr, &n_to_addr);
        if (nRead > 0)
        {
            SOCKADDR_IN* pSIN = (SOCKADDR_IN*)&to_addr;
            printf("[%d.%d.%d.%d]recv=%d\n", pSIN->sin_addr.s_net, pSIN->sin_addr.s_host, pSIN->sin_addr.s_lh, pSIN->sin_addr.s_impno, nRead);
            //printf("%.*s\n", nRead, pData);
            if (strstr(pData, "dn:NetworkVideoTransmitter") != NULL)
            {
                //struct sockaddr_in to_addr;
                //memset(&to_addr, 0, sizeof(to_addr));
                //to_addr.sin_family = AF_INET;
                //to_addr.sin_addr.s_addr = inet_addr("192.168.1.252");
                //to_addr.sin_port = htons(3709);
                //char *data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                //    "<env:Envelope xmlns:env=\"http://www.w3.org/2003/05/soap-envelope\"><env:Header><wsadis:MessageID>urn:uuid:59b20000-e1d4-11b4-8385-acb92f419687</wsadis:MessageID>"
                //    "<wsadis:RelatesTo>uuid:de0c7de6-77ae-4e83-850a-6e34417d9ffe</wsadis:RelatesTo>"
                //    "<wsadis:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsadis:To>"
                //    "<wsadis:Action>http://schemas.xmlsoap.org/ws/2005/04/discovery/ProbeMatches</wsadis:Action>"
                //    "<d:AppSequence InstanceId=\"1729502470\" MessageNumber=\"103\"/>"
                //    "</env:Header>"
                //    "<env:Body><d:ProbeMatches><d:ProbeMatch><wsadis:EndpointReference><wsadis:Address>urn:uuid:59b20000-e1d4-11b4-8385-acb92f419687</wsadis:Address>"
                //    "</wsadis:EndpointReference>"
                //    "<d:Types>dn:NetworkVideoTransmitter tds:Device</d:Types>"
                //    "<d:Scopes>onvif://www.onvif.org/type/video_encoder onvif://www.onvif.org/Profile/Streaming onvif://www.onvif.org/Profile/G onvif://www.onvif.org/Profile/T onvif://www.onvif.org/type/audio_encoder onvif://www.onvif.org/type/ptz onvif://www.onvif.org/MAC/ac:b9:2f:41:96:87 onvif://www.onvif.org/hardware/iDS-2ZMN3209N onvif://www.onvif.org/name/HIKVISION%20iDS-2ZMN3209N</d:Scopes>"
                //    "<d:XAddrs>http://192.168.1.200/onvif/device_service</d:XAddrs>"
                //    "<d:MetadataVersion>10</d:MetadataVersion>"
                //    "</d:ProbeMatch>"
                //    "</d:ProbeMatches>"
                //    "</env:Body>"
                //    "</env:Envelope>";
                //char* data = "<d:Scopes>onvif://www.onvif.org/type/video_encoder onvif://www.onvif.org/Profile/Streaming onvif://www.onvif.org/Profile/G onvif://www.onvif.org/Profile/T onvif://www.onvif.org/type/audio_encoder onvif://www.onvif.org/type/ptz onvif://www.onvif.org/MAC/ac:b9:2f:41:96:87 onvif://www.onvif.org/hardware/iDS-2ZMN3209N onvif://www.onvif.org/name/HIKVISION%20iDS-2ZMN3209N</d:Scopes>"
                //        "<d:XAddrs>http://192.168.1.200/onvif/device_service http://[fe80::aeb9:2fff:fe41:9687]/onvif/device_service</d:XAddrs>";
                char data[10240] = { 0 };
                //sprintf(data, "<d:Scopes>onvif://www.onvif.org/type/video_encoder onvif://www.onvif.org/Profile/Streaming onvif://www.onvif.org/Profile/G onvif://www.onvif.org/Profile/T onvif://www.onvif.org/type/audio_encoder onvif://www.onvif.org/type/ptz onvif://www.onvif.org/MAC/ac:b9:2f:41:96:87 onvif://www.onvif.org/hardware/iDS-2ZMN3209N onvif://www.onvif.org/name/HIKVISION%%20iDS-2ZMN3209N</d:Scopes>"
                //    "<d:XAddrs>http://192.168.1.%d/onvif/device_service http://[fe80::aeb9:2fff:fe41:9687]/onvif/device_service</d:XAddrs>", n);
                sprintf(data, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                        "<env:Envelope xmlns:env=\"http://www.w3.org/2003/05/soap-envelope\"><env:Header><wsadis:MessageID>urn:uuid:59b20000-e1d4-11b4-8385-acb92f419687</wsadis:MessageID>"
                        "<wsadis:RelatesTo>uuid:de0c7de6-77ae-4e83-850a-6e34417d9ffe</wsadis:RelatesTo>"
                        "<wsadis:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsadis:To>"
                        "<wsadis:Action>http://schemas.xmlsoap.org/ws/2005/04/discovery/ProbeMatches</wsadis:Action>"
                        "<d:AppSequence InstanceId=\"1729502470\" MessageNumber=\"103\"/>"
                        "</env:Header>"
                        "<env:Body><d:ProbeMatches><d:ProbeMatch><wsadis:EndpointReference><wsadis:Address>urn:uuid:59b20000-e1d4-11b4-8385-acb92f419687</wsadis:Address>"
                        "</wsadis:EndpointReference>"
                        "<d:Types>dn:NetworkVideoTransmitter tds:Device</d:Types>"
                        "<d:Scopes>onvif://www.onvif.org/type/video_encoder onvif://www.onvif.org/Profile/Streaming onvif://www.onvif.org/Profile/G onvif://www.onvif.org/Profile/T onvif://www.onvif.org/type/audio_encoder onvif://www.onvif.org/type/ptz onvif://www.onvif.org/MAC/ac:b9:2f:41:96:87 onvif://www.onvif.org/hardware/iDS-2ZMN3209N onvif://www.onvif.org/name/HIKVISION%%20iDS-2ZMN3209N</d:Scopes>"
                        "<d:XAddrs>http://192.168.1.%d/onvif/device_service</d:XAddrs>"
                        "<d:MetadataVersion>10</d:MetadataVersion>"
                        "</d:ProbeMatch>"
                        "</d:ProbeMatches>"
                        "</env:Body>"
                        "</env:Envelope>", nNum);
                int nSend = sendto(server_udp, data, strlen(data), 0, &to_addr, sizeof(to_addr));
                if (nSend > 0)
                {
                    printf("[localhost]send=%d\n", nSend);
                    //printf("%.*s\n", strlen(data), data);
                }
            }
        }
    }
    free(pData);
    return(0);
}
void Usage()
{
    printf("Usage:\n\todds.exe --[192.168.1.200]\n\todds 201 --[192.168.1.201]\n\todds 202 10 --[192.168.1.202,192.168.1.212]\n");
}
int main(int argc, char** argv)
{
    int* pId = NULL;
    int nCnt = 0;
    int nStart = 200;
    if (argc == 1)
    {
        nCnt = 1;
    }
    else if (argc == 2)
    {
        nCnt = 1;
        nStart = atoi(argv[1]);
    }
    else if (argc == 3)
    {
        nCnt = atoi(argv[2]);
        nStart = atoi(argv[1]);
    }
    if (nCnt <= 0 || nCnt >= 254 || nStart <= 1 || nStart >= 255)
    {
        Usage();
        getchar();
        return(0);
    }
    pId = (int*)malloc(nCnt * sizeof(int));
    if (pId == NULL)
    {
        printf("Memory allocate failed!\n");
        getchar();
        return(0);
    }
    WSADATA wsadata = { 0,0, };
    WSAStartup(MAKEWORD(2, 2), &wsadata);
    for (int i = 0; i < nCnt; i++)
    {
        pId[i] = nStart + i;
        CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)DeviceDiscoveryServer, &pId[i], NULL, NULL);
    }
    getchar();
    free(pId);
    WSACleanup();
}


×
打赏作者
最新回复 (0)
查看全部
全部楼主
返回