常用头文件API实现

xingyun86 8月前 276

常用头文件API实现

// pch.h: This is a precompiled header file.
// Files listed below are compiled only once, improving build performance for future builds.
// This also affects IntelliSense performance, including code completion and many code browsing features.
// However, files listed here are ALL re-compiled if any one of them is updated between builds.
// Do not add files here that you will be updating frequently as this negates the performance advantage.
#ifndef PCH_H
#define PCH_H
// add headers that you want to pre-compile here
#include "framework.h"
#include <mutex>
#include <string>
#include <thread>
#include <vector>
#include <random>
#include <sstream>
#include <fstream>
#include <filesystem>
__inline static
std::string getuuid() 
{
    static std::random_device rd;
    static std::uniform_int_distribution<uint64_t> dist(0ULL, 0xFFFFFFFFFFFFFFFFULL);
    uint64_t ab = dist(rd);
    uint64_t cd = dist(rd);
    uint32_t a, b, c, d;
    std::stringstream ss;
    ab = (ab & 0xFFFFFFFFFFFF0FFFULL) | 0x0000000000004000ULL;
    cd = (cd & 0x3FFFFFFFFFFFFFFFULL) | 0x8000000000000000ULL;
    a = (ab >> 32U);
    b = (ab & 0xFFFFFFFFU);
    c = (cd >> 32U);
    d = (cd & 0xFFFFFFFFU);
    ss << std::hex << std::nouppercase << std::setfill('0');
    ss << std::setw(8) << (a) << '-';
    ss << std::setw(4) << (b >> 16U) << '-';
    ss << std::setw(4) << (b & 0xFFFFU) << '-';
    ss << std::setw(4) << (c >> 16U) << '-';
    ss << std::setw(4) << (c & 0xFFFFU);
    ss << std::setw(8) << d;
    return ss.str();
}
__inline static
std::string getuuid(bool dash = true, bool uppercase = true)
{
    static std::random_device rd;
    static std::uniform_int_distribution<uint64_t> dist(0ULL, 0xFFFFFFFFFFFFFFFFULL);
    uint64_t ab = dist(rd);
    uint64_t cd = dist(rd);
    uint32_t a, b, c, d;
    std::stringstream ss;
    ab = (ab & 0xFFFFFFFFFFFF0FFFULL) | 0x0000000000004000ULL;
    cd = (cd & 0x3FFFFFFFFFFFFFFFULL) | 0x8000000000000000ULL;
    a = (ab >> 32U);
    b = (ab & 0xFFFFFFFFU);
    c = (cd >> 32U);
    d = (cd & 0xFFFFFFFFU);
    ss << std::hex << ((uppercase == true) ? std::uppercase : std::nouppercase) << std::setfill('0');
    ss << std::setw(8) << (a);
    if (dash == true) ss << '-';
    ss << std::setw(4) << (b >> 16U);
    if (dash == true) ss << '-';
    ss << std::setw(4) << (b & 0xFFFFU);
    if (dash == true) ss << '-';
    ss << std::setw(4) << (c >> 16U);
    if (dash == true) ss << '-';
    ss << std::setw(4) << (c & 0xFFFFU);
    ss << std::setw(8) << d;
    return ss.str();
}
class ConsoleManager
{
    FILE* pStdIn = NULL;
    FILE* pStdOut = NULL;
    FILE* pStdErr = NULL;
public:
    static ConsoleManager* CM()
    {
        static ConsoleManager ConsoleManagerInstance = {};
        return &ConsoleManagerInstance;
    }
public:
    void FormatPrintf(const char* format, ...)
    {
        va_list va = nullptr;
        va_start(va, format);
        if (pStdOut != NULL)
        {
            ::vfprintf(pStdOut, format, va);
            ::fflush(pStdOut);
        }
        else
        {
            ::vfprintf(stdout, format, va);
        }
        va_end(va);
    }
    void FormatPrintfW(const wchar_t* format, ...)
    {
        va_list va = nullptr;
        va_start(va, format); 
        if (pStdOut != NULL)
        {
            ::vfwprintf(pStdOut, format, va);
            ::fflush(pStdOut);
        }
        else
        {
            ::vfwprintf(stdout, format, va);
        }
        va_end(va);
    }
    void StartConsole()
    {
        ::setlocale(LC_ALL, ("chs"));
        if (::AllocConsole() == TRUE)
        {
            ::freopen_s(&pStdIn, ("CONIN$"), ("r"), stdin);
            ::freopen_s(&pStdOut, ("CONOUT$"), ("w"), stdout);
            ::freopen_s(&pStdErr, ("CONOUT$"), ("w"), stderr);
        }
    }
    void CloseConsole()
    {
        if (pStdIn != NULL)
        {
            ::fclose(pStdIn);
            pStdIn = NULL;
        }
        if (pStdOut != NULL)
        {
            ::fclose(pStdOut);
            pStdOut = NULL;
        }
        if (pStdErr != NULL)
        {
            ::fclose(pStdErr);
            pStdErr = NULL;
        }
        ::FreeConsole();
    }
public:
    ConsoleManager()
    {
#if defined(_DEBUG) || defined(DEBUG)
        StartConsole();
#endif
    }
    virtual ~ConsoleManager()
    {
#if defined(_DEBUG) || defined(DEBUG)
        CloseConsole();
#endif
    }
};
class CPing {
    typedef HANDLE(WINAPI*PFN_IcmpCreateFile)();
    typedef DWORD(WINAPI*PFN_IcmpSendEcho)(
        HANDLE                 IcmpHandle,
        IPAddr                 DestinationAddress,
        LPVOID                 RequestData,
        WORD                   RequestSize,
        PIP_OPTION_INFORMATION RequestOptions,
        LPVOID                 ReplyBuffer,
        DWORD                  ReplySize,
        DWORD                  Timeout
        );
    typedef DWORD(WINAPI*PFN_IcmpParseReplies)(
        LPVOID ReplyBuffer,
        DWORD  ReplySize
        );
    typedef BOOL(WINAPI*PFN_IcmpCloseHandle)(
        HANDLE IcmpHandle
        );
public:
    CPing() {
        hModule = GetModuleHandle(TEXT("IPHLPAPI"));
        if (hModule == nullptr)
        {
            hModule = LoadLibrary(TEXT("IPHLPAPI"));
            if (hModule != nullptr)
            {
                bLoad = true;
            }
            else
            {
                hModule = GetModuleHandle(TEXT("ICMP"));
                if (hModule == nullptr)
                {
                    hModule = LoadLibrary(TEXT("ICMP"));
                    if (hModule != nullptr)
                    {
                        bLoad = true;
                    }
                }
            }
        }
        if (hModule != nullptr)
        {
            fnIcmpCreateFile = (PFN_IcmpCreateFile)GetProcAddress(hModule, "IcmpCreateFile");
            fnIcmpSendEcho = (PFN_IcmpSendEcho)GetProcAddress(hModule, "IcmpSendEcho");
            fnIcmpParseReplies = (PFN_IcmpParseReplies)GetProcAddress(hModule, "IcmpParseReplies");
            fnIcmpCloseHandle = (PFN_IcmpCloseHandle)GetProcAddress(hModule, "IcmpCloseHandle");
        }
    }
    ~CPing() {
        if (bLoad == true)
        {
            fnIcmpCreateFile = nullptr;
            fnIcmpSendEcho = nullptr;
            fnIcmpParseReplies = nullptr;
            fnIcmpCloseHandle = nullptr;
            FreeLibrary(hModule);
            hModule = nullptr;
            bLoad = false;
        }
    }
private:
    bool bLoad = false;
    HMODULE hModule = nullptr;
    PFN_IcmpCreateFile fnIcmpCreateFile = nullptr;
    PFN_IcmpSendEcho fnIcmpSendEcho = nullptr;
    PFN_IcmpParseReplies fnIcmpParseReplies = nullptr;
    PFN_IcmpCloseHandle fnIcmpCloseHandle = nullptr;
    bool IsAvailable()
    {
        return ((fnIcmpCreateFile != nullptr) && (fnIcmpSendEcho != nullptr) && (fnIcmpParseReplies != nullptr) && (fnIcmpCloseHandle != nullptr));
    }
public:
    static bool ping_main(const std::string& ip)
    {
        bool result = false;
        DWORD dwRet = 0;
        // Declare and initialize variables
        HANDLE hIcmpFile = INVALID_HANDLE_VALUE;
        ULONG ipAddr = INADDR_NONE;
        CHAR SendData[4] = "ACK";
        DWORD ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData);
        BYTE ReplyBuffer[sizeof(ICMP_ECHO_REPLY) + sizeof(SendData)] = { 0 };
        if (Inst()->IsAvailable())
        {
            // Validate the parameters
            ipAddr = inet_addr(ip.c_str());
            if (ipAddr == INADDR_NONE) {
                return false;
            }
            hIcmpFile = Inst()->fnIcmpCreateFile();
            if (hIcmpFile != INVALID_HANDLE_VALUE)
            {
                dwRet = Inst()->fnIcmpSendEcho(hIcmpFile, ipAddr, SendData, sizeof(SendData), NULL, ReplyBuffer, ReplySize, 1000);
                if (dwRet != 0)
                {
                    PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
                    if (pEchoReply->Status == IP_SUCCESS)
                    {
                        result = true;
                    }
                }
                Inst()->fnIcmpCloseHandle(hIcmpFile);
            }
        }
        return result;
    }
public:
    static CPing* Inst()
    {
        static CPing CPingInstance;
        return &CPingInstance;
    }
};
#include <TlHelp32.h>
__inline static
BOOL EnableDebugPrivilege()
{
    DWORD rl = 0L;
    HANDLE ht = NULL;
    LUID luid = { 0 };
    TOKEN_PRIVILEGES tp = { 0 };
    tp.PrivilegeCount = 1;
    tp.Privileges->Luid = luid;
    tp.Privileges->Attributes = SE_PRIVILEGE_ENABLED;
    ::LookupPrivilegeValueW(NULL, SE_DEBUG_NAME, &luid);
    ::OpenProcessToken(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &ht);
    ::AdjustTokenPrivileges(ht, FALSE, &tp, sizeof(tp), NULL, &rl);
    ::CloseHandle(ht);
    return TRUE;
}
__inline static
void KillallProcess(LPCWSTR lpcwProcessName)
{
    DWORD e = 0;
    WCHAR ss[MAX_PATH] = { 0 };
    LPVOID lpMsgBuf = NULL;
    long re = 0;
    BOOL bResult = FALSE;
    HANDLE hSnapShot = NULL;
    PROCESSENTRY32W PE32W = { 0 };
    hSnapShot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    e = ::GetLastError();
    if (hSnapShot == NULL)
    {
        ::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&lpMsgBuf, 0, NULL);
        if (lpMsgBuf != NULL)
        {
            ::_snwprintf_s(ss, sizeof(ss) / sizeof(*ss), L"%s", (LPWSTR)lpMsgBuf);
            ::LocalFree(lpMsgBuf);
        }
        if (e != 0)::MessageBoxW(NULL, ss, (L"GWPID -> CreateToolhelp32Snapshot"), MB_OK);
    }
    else
    {
        PE32W.dwSize = sizeof(PE32W);
        bResult = ::Process32FirstW(hSnapShot, &PE32W);
        e = ::GetLastError();
        if (bResult == FALSE)
        {
            ::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&lpMsgBuf, 0, NULL);
            if (lpMsgBuf != NULL)
            {
                ::_snwprintf_s(ss, sizeof(ss) / sizeof(*ss), L"%s", (LPWSTR)lpMsgBuf);
                ::LocalFree(lpMsgBuf);
            }
            if (e != 0)::MessageBoxW(NULL, ss, (L"GWPID -> Process32First"), MB_OK);
        }
        while (bResult != FALSE)
        {
            if (::_wcsicmp(PE32W.szExeFile, lpcwProcessName) == 0 && PE32W.th32ProcessID != ::GetCurrentProcessId())
            {
                HANDLE hP = NULL;
                hP = ::OpenProcess(PROCESS_ALL_ACCESS, false, PE32W.th32ProcessID);
                e = ::GetLastError();
                if (hP == NULL)
                {
                    ::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&lpMsgBuf, 0, NULL);
                    if (lpMsgBuf != NULL)
                    {
                        ::_snwprintf_s(ss, sizeof(ss) / sizeof(*ss), L"%s", (LPWSTR)lpMsgBuf);
                        ::LocalFree(lpMsgBuf);
                    }
                    if (e != 0)::MessageBoxW(NULL, ss, (L"SW -> OpenProcess"), MB_OK);
                }
                if (hP != NULL)
                {
                    ::TerminateProcess(hP, (0));
                    ::CloseHandle(hP);
                }
            }
            bResult = ::Process32NextW(hSnapShot, &PE32W);
            e = ::GetLastError();
            if (bResult == FALSE && e != ERROR_NO_MORE_FILES)
            {
                ::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&lpMsgBuf, 0, NULL);
                if (lpMsgBuf != NULL)
                {
                    ::_snwprintf_s(ss, sizeof(ss) / sizeof(*ss), L"%s", (LPWSTR)lpMsgBuf);
                    ::LocalFree(lpMsgBuf);
                }
                if (e != 0)::MessageBoxW(NULL, ss, (L"GWPID -> Process32Next"), MB_OK);
            }
        }
        ::CloseHandle(hSnapShot);
    }
    return;
}
__inline static
INT RunCmd(LPCWSTR lpApplicationName, LPWSTR lpCommandLine = NULL,
    INT(__stdcall* cbEnter)(STARTUPINFOW&, PROCESS_INFORMATION&, BOOL&, DWORD&, LPWSTR, LPVOID) = NULL,
    INT(__stdcall* cbStart)(STARTUPINFOW&, PROCESS_INFORMATION&, BOOL&, DWORD&, LPWSTR, LPVOID) = NULL,
    INT(__stdcall* cbLeave)(STARTUPINFOW&, PROCESS_INFORMATION&, BOOL&, DWORD&, LPWSTR, LPVOID) = NULL,
    LPVOID lp = NULL)
{
    BOOL bi = FALSE;
    STARTUPINFOW si = { 0 };
    WCHAR cd[MAX_PATH] = { 0 };
    DWORD cf = CREATE_NO_WINDOW;
    PROCESS_INFORMATION pi = { 0 };
    memset(&si, 0, sizeof(si));
    memset(&pi, 0, sizeof(pi));
    si.cb = sizeof(si);
    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_HIDE;
    if (cbEnter != NULL)
    {
        if (cbEnter(si, pi, bi, cf, cd, lp) != 0)
        {
            return(-1);
        }        
    }
    if (::CreateProcessW(lpApplicationName, lpCommandLine, NULL, NULL, bi, cf, NULL, ((*cd == L'\0') ? NULL : cd), &si, &pi) == TRUE)
    {
        if (cbStart != NULL)
        {
            if (cbStart(si, pi, bi, cf, cd, lp) != 0)
            {
                ::TerminateProcess(pi.hProcess, (0U));
                return(-1);
            }
        }
        ::WaitForSingleObject(pi.hProcess, INFINITE);
        ::CloseHandle(pi.hProcess);
        ::CloseHandle(pi.hThread);
    }
    if (cbLeave!= NULL)
    {
        if (cbLeave(si, pi, bi, cf, cd, lp) != 0)
        {
           return(-1);
        }
    }
    return(0);
}
__inline static
std::wstring w_run_cmd(LPCWSTR lpCmdLine, LPCWSTR lpApplicationName = NULL,
    const std::function<void(DWORD nWaitState, LPCWSTR lpcText, LPVOID lpUserData)>& cbCallBack = NULL, LPVOID lpUserData = NULL)
{
    std::wstring ret = std::wstring();
    const DWORD PLY_PIPE_SIZE = 16384;
    BOOL bRet = FALSE;
    HANDLE hpr = NULL;
    HANDLE hpw = NULL;
    SECURITY_ATTRIBUTES sa = { 0 };
    STARTUPINFOW siw = { 0 };
    PROCESS_INFORMATION pi = { 0 };
    DWORD dwNumberOfBytesRead = 0;
    DWORD dwNumberOfBytesToRead = 0;
    CHAR czBuffer[PLY_PIPE_SIZE] = { 0 };
    ::memset(&sa, 0, sizeof(sa));
    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;
    bRet = ::CreatePipe(&hpr, &hpw, &sa, PLY_PIPE_SIZE);
    if (bRet == TRUE)
    {
        ::memset(&siw, 0, sizeof(siw));
        siw.cb = sizeof(siw);
        siw.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
        siw.hStdOutput = hpw;
        siw.hStdError = hpw;
        siw.wShowWindow = SW_HIDE;
        ::memset(&pi, 0, sizeof(pi));
        bRet = ::CreateProcessW(lpApplicationName, (LPWSTR)lpCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &siw, &pi);
        if (bRet == FALSE)
        {
            int nRet = GetLastError();
            printf("CreateProcess last error %d \n", nRet);
        }
        else
        {
            for (DWORD dwRet = ::WaitForSingleObject(pi.hProcess, WAIT_TIMEOUT); ; dwRet = ::WaitForSingleObject(pi.hProcess, WAIT_TIMEOUT))
            {
                if (dwRet == WAIT_TIMEOUT)
                {
                    bRet = ::PeekNamedPipe(hpr, NULL, 0, NULL, &dwNumberOfBytesToRead, NULL);
                    if (bRet == TRUE && dwNumberOfBytesToRead > 0)
                    {
                        ::memset(czBuffer, 0, sizeof(czBuffer));
                        bRet = ::ReadFile(hpr, czBuffer, dwNumberOfBytesToRead, &dwNumberOfBytesRead, NULL);
                        if (bRet == TRUE)
                        {
                            ret.append(UTF8ToWIDE(czBuffer).c_str());
                            if (cbCallBack != NULL)
                            {
                                cbCallBack(dwRet, UTF8ToWIDE(czBuffer).c_str(), lpUserData);
                            }
                        }
                    }
                }
                else
                {
                    if (dwRet == WAIT_OBJECT_0)
                    {
                        bRet = ::PeekNamedPipe(hpr, NULL, 0, NULL, &dwNumberOfBytesToRead, NULL);
                        if (bRet == TRUE && dwNumberOfBytesToRead > 0)
                        {
                            ::memset(czBuffer, 0, sizeof(czBuffer));
                            bRet = ::ReadFile(hpr, czBuffer, dwNumberOfBytesToRead, &dwNumberOfBytesRead, NULL);
                            if (bRet == TRUE)
                            {
                                ret.append(UTF8ToWIDE(czBuffer).c_str());
                                if (cbCallBack != NULL)
                                {
                                    cbCallBack(dwRet, UTF8ToWIDE(czBuffer).c_str(), lpUserData);
                                }
                            }
                        }
                    }
                    if (cbCallBack != NULL)
                    {
                        cbCallBack(dwRet, NULL, lpUserData);
                    }
                    break;
                }
            }
        }
        if (pi.hProcess != NULL)
        {
            ::CloseHandle(pi.hProcess);
            pi.hProcess = NULL;
        }
        if (pi.hThread)
        {
            ::CloseHandle(pi.hThread);
            pi.hThread = NULL;
        }
    }
    if (hpr != NULL)
    {
        ::CloseHandle(hpr);
        hpr = NULL;
    }
    if (hpw != NULL)
    {
        ::CloseHandle(hpw);
        hpr = NULL;
    }
    return ret;
}


#include <mstcpip.h>
#include <ws2tcpip.h>
__inline static
INT EnumHostAddr(std::vector<std::string>& vs)
{
    char ip[16] = { 0 };
    struct in_addr* ia = NULL;
    struct hostent* ph = NULL;
    char hn[MAX_HOSTNAME_LEN] = { 0 };
    if (::gethostname(hn, sizeof(hn)) != 0)
    {
        return (-2);
    }
    ph = ::gethostbyname(hn);
    if (ph == NULL)
    {
        return (-1);
    }
    for (char** ha = ph->h_addr_list; *ha != NULL; ha++)
    {
        ia = *(struct in_addr**)ha;
        ::memset(ip, 0, sizeof(ip));
        ::snprintf(ip, sizeof(ip) / sizeof(*ip), "%d.%d.%d.%d", ia->S_un.S_un_b.s_b1, ia->S_un.S_un_b.s_b2, ia->S_un.S_un_b.s_b3, ia->S_un.S_un_b.s_b4);
        if (::strstr(ip, ("192.168.1.")) != NULL)
        {
            vs.emplace_back(ip);
        }
    }
    return(0);
}
__inline static
INT OnvifDiscovery(std::vector<std::string>& vsresp, INT(__stdcall* cb)(INT, INT, LPVOID) = NULL, LPVOID lp = NULL)
{
    int r = 0;
    std::mutex lock = {};
    std::vector<std::string> vs = {};
    std::vector<std::thread> vt = {};
    EnumHostAddr(vs);
    for (auto & it : vs)
    {
        vt.emplace_back(std::thread([&]()
            {
                unsigned long e = 0;
                unsigned long iv = RCVALL_ON;
                unsigned long ov = 0;
                unsigned long vd = 0;
                unsigned long ve = 1;
                SOCKET s = INVALID_SOCKET;
                unsigned long br = sizeof(ov);
                struct ip_mreq ipmreq = { 0 };
                struct sockaddr_in sain_sendto = { 0 };
                struct sockaddr_in sain_bindto = { 0 };
                //std::vector<std::string> vsresp = {};
                const std::vector<std::string>& vsreq =
                {
                    "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\"><s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</a:Action><a:MessageID>uuid:" + getuuid() + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><a:To s:mustUnderstand=\"1\">urn:schemas-xmlsoap-org:ws:2005:04:discovery</a:To></s:Header><s:Body><Probe xmlns=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\"><d:Types xmlns:d=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\" xmlns:dp0=\"http://www.onvif.org/ver10/network/wsdl\">dp0:NetworkVideoTransmitter</d:Types></Probe></s:Body></s:Envelope>",
                    "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\"><s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</a:Action><a:MessageID>uuid:" + getuuid() + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><a:To s:mustUnderstand=\"1\">urn:schemas-xmlsoap-org:ws:2005:04:discovery</a:To></s:Header><s:Body><Probe xmlns=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\"><d:Types xmlns:d=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\" xmlns:dp0=\"http://www.onvif.org/ver10/network/wsdl\">dp0:NetworkVideoDisplay</d:Types></Probe></s:Body></s:Envelope>",
                    "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\"><s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</a:Action><a:MessageID>uuid:" + getuuid() + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><a:To s:mustUnderstand=\"1\">urn:schemas-xmlsoap-org:ws:2005:04:discovery</a:To></s:Header><s:Body><Probe xmlns=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\"><d:Types xmlns:d=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\" xmlns:dp0=\"http://www.onvif.org/ver10/device/wsdl\">dp0:Device</d:Types></Probe></s:Body></s:Envelope>",
                    "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\"><s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</a:Action><a:MessageID>uuid:" + getuuid() + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><a:To s:mustUnderstand=\"1\">urn:schemas-xmlsoap-org:ws:2005:04:discovery</a:To></s:Header><s:Body><Probe xmlns=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\"><d:Types xmlns:d=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\" xmlns:dp0=\"http://www.onvif.org/ver10/network/wsdl\">dp0:NetworkVideoTransmitter</d:Types></Probe></s:Body></s:Envelope>",
                    "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\"><s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</a:Action><a:MessageID>uuid:" + getuuid() + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><a:To s:mustUnderstand=\"1\">urn:schemas-xmlsoap-org:ws:2005:04:discovery</a:To></s:Header><s:Body><Probe xmlns=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\"><d:Types xmlns:d=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\" xmlns:dp0=\"http://www.onvif.org/ver10/network/wsdl\">dp0:NetworkVideoDisplay</d:Types></Probe></s:Body></s:Envelope>",
                    "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\"><s:Header><a:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</a:Action><a:MessageID>uuid:" + getuuid() + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><a:To s:mustUnderstand=\"1\">urn:schemas-xmlsoap-org:ws:2005:04:discovery</a:To></s:Header><s:Body><Probe xmlns=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\"><d:Types xmlns:d=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\" xmlns:dp0=\"http://www.onvif.org/ver10/device/wsdl\">dp0:Device</d:Types></Probe></s:Body></s:Envelope>",
                };
                unsigned long rto = (1000 / (vsreq.size() - 1)) + (1000 % (vsreq.size() - 1)) + 100;
                ::memset(&sain_sendto, 0, sizeof(sain_sendto));
                sain_sendto.sin_family = AF_INET;
                sain_sendto.sin_addr.s_addr = ::inet_addr("239.255.255.250");
                sain_sendto.sin_port = ::htons(3702);
                ::memset(&sain_bindto, 0, sizeof(sain_bindto));
                sain_bindto.sin_family = AF_INET;
                sain_bindto.sin_addr.s_addr = inet_addr(it.c_str());
                sain_bindto.sin_port = htons(0);
                memset(&ipmreq, 0, sizeof(ipmreq));
                ipmreq.imr_multiaddr.s_addr = ::inet_addr("239.255.255.250");    // 鲥Դ  ַ
                ipmreq.imr_interface.s_addr = INADDR_ANY;					    //   ص ַ
                s = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
                if (s == INVALID_SOCKET)
                {
                    printf("%s:%d socket() error.%d\n", __func__, __LINE__, ::WSAGetLastError());
                    return(-1);
                }
                r = ::setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char*)&ve, sizeof(ve));
                if (r != 0)
                {
                    printf("%s:%d setsockopt() error.%d\n", __func__, __LINE__, ::WSAGetLastError());
                }
                r = ::setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (const char*)&rto, sizeof(rto));
                if (r != 0)
                {
                    printf("%s:%d setsockopt() error.%d\n", __func__, __LINE__, ::WSAGetLastError());
                }
                //r = ::setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&ipmreq, sizeof(ipmreq));
                //if (r != 0)
                //{
                //    printf("%s:%d setsockopt() error.%d\n", __func__, __LINE__, ::WSAGetLastError());
                //}
                //r = ::setsockopt(s, SOL_SOCKET, SO_BROADCAST, (const char*)&ve, sizeof(ve));
                //if (r != 0)
                //{
                //    printf("%s:%d setsockopt() error.%d\n", __func__, __LINE__, ::WSAGetLastError());
                //}
                //r = ::setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, (const char*)&vd, sizeof(vd));
                //if (r != 0)
                //{
                //    printf("%s:%d setsockopt() error.%d\n", __func__, __LINE__, ::WSAGetLastError());
                //}
                r = ::bind(s, (const struct sockaddr*)&sain_bindto, sizeof(sain_bindto));
                if (r != 0)
                {
                    printf("%s:%d setsockopt() error.%d\n", __func__, __LINE__, ::WSAGetLastError());
                }
                //if (::WSAIoctl(s, SIO_RCVALL, &iv, sizeof(iv), &ov, sizeof(ov), &br, NULL, NULL) == SOCKET_ERROR)
                //{
                //    printf("WSAIotcl(%ul) failed with error code %d\n", SIO_RCVALL, WSAGetLastError());
                //    //return -1;
                //}
                //else
                //{
                //    printf("WSAIotcl(%ul) is OK!\n", SIO_RCVALL);
                //}
                for (int nid = 0, cnt = vsreq.size(); nid < cnt; nid++)
                {
                    r = ::sendto(s, vsreq.at(nid).c_str(), vsreq.at(nid).length(), 0, (const struct sockaddr*)&sain_sendto, sizeof(sain_sendto));
                    if (r > 0)
                    {
                        while (true)
                        {
                            char resp[16384] = { 0 };
                            r = ::recvfrom(s, resp, sizeof(resp) / sizeof(*resp), 0, NULL, NULL);
                            e = ::WSAGetLastError();
                            if (r > 0)
                            {
                                lock.lock();
                                vsresp.emplace_back(resp);
                                lock.unlock();
                            }
                            else
                            {
                                if (e == WSAETIMEDOUT)
                                {
                                    ;//ConsoleManager::CM()->Printf("recvfrom timeout!\n");
                                }
                                break;
                            }
                        }
                    }
                    else
                    {
                        printf("%s:%d sendto() error.%d\n", __func__, __LINE__, ::WSAGetLastError());
                    }
                    if (cb != NULL)
                    {
                        if (cb(nid, cnt, lp) != 0)
                        {
                            break;
                        }
                    }
                }
                ::closesocket(s);
            }));
    }
    for (auto & it : vt)
    {
        if (it.joinable() == true)
        {
            it.join();
        }
    }
    return(0);
}
#endif //PCH_H


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