UDP主机扫描源码

先看一下运行效果图:

头文件声明:

class ScanUDP 
{

public:

    /* @接口 默认构造函数
     * @邮箱 [email protected]
     * @时间 2018年12月21号
     */
    ScanUDP();

    /* @接口 默认析构函数
     * @邮箱 [email protected]
     * @时间 2018年12月21号
     */
    ~ScanUDP();
    
    /* @接口 停止扫描
     * @返回 bool 成功返回值为true,否则返回值为false
     * @邮箱 [email protected]
     * @时间 2018年12月19号
     */
    virtual void stopUDPScan();
    
    /* @接口 
     * @返回 bool 成功返回值为true,否则返回值为false
     * @邮箱 [email protected]
     * @时间 2019年1月11号
     */
    virtual bool beginUDPScan();

    /* @接口 设置目标端口
     * @参数 ULongArr 目标端口,如果不设置,那么对所有端口进行扫描
     * @返回 bool 成功返回值为true,否则返回值为false
     * @邮箱 [email protected]
     * @时间 2019年1月11号
     */
    virtual void setDesPort(const ULongArr &);

    /* @接口 设置扫描回调函数
     * @返回 bool 成功返回值为true,否则返回值为false
     * @邮箱 [email protected]
     * @时间 2018年12月18号
     */
    virtual void setSyntonyFunc(const DoxExtraFunc &);

    /* @接口 开始扫描
     * @参数 ulong 扫描的ip地址
     * @参数 ulong 超时限制时间
     * @返回 bool 成功返回值为true,否则返回值为false
     * @邮箱 [email protected]
     * @时间 2018年12月13号
     */
    virtual bool setUDPScanIP(ulong, ulong, ulong timeOut = 128);
    
    /* @接口 开始扫描
     * @参数 QString 扫描的ip地址
     * @参数 ulong 超时限制时间
     * @返回 bool 成功返回值为true,否则返回值为false
     * @邮箱 [email protected]
     * @时间 2019年1月11号
     */
    virtual bool setUDPScanIP(const QString &, ulong timeOut = 128);
    
    /* @接口 开始扫描
     * @参数 ULongArr 扫描的ip地址集合
     * @参数 ulong 超时限制时间
     * @返回 bool 成功返回值为true,否则返回值为false
     * @邮箱 [email protected]
     * @时间 2019年1月11号
     */
    virtual bool setUDPScanIPs(const ULongArr &, ulong timeOut = 128);
    
    /* @接口 开始扫描
     * @参数 QStringList 扫描的ip地址集合
     * @参数 ulong 超时限制时间
     * @返回 bool 成功返回值为true,否则返回值为false
     * @邮箱 [email protected]
     * @时间 2019年1月11号
     */
    virtual bool setUDPScanIPs(const QStringList &, ulong timeOut = 128);

private:

    /* @接口
     * @邮箱 [email protected]
     * @时间 2019年1月11号
     */
    bool initSocket();

    /* @接口
     * @邮箱 [email protected]
     * @时间 2019年1月11号
     */
    static ulong udpScanThread(void *);

public:

    bool m_init;
    bool m_stop;
    ulong m_sock;
    ULongArr m_ips;
    ULongArr m_ports;
    ulong m_dwTimeout;
    DoxExtraFunc m_func;

};

源文件定义:

ScanUDP::ScanUDP()
    , m_stop(false)
    , m_init(false)
    , m_dwTimeout(128)
{
    WSADATA wsaData; initSocket();
    WORD wVersionRequested = MAKEWORD(2, 2);
    if(WSAStartup(wVersionRequested, &wsaData))
    {
        DoxLogger("Winsock Initialization failed");
        exit(1);
    }
    m_sock = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0, WSA_FLAG_OVERLAPPED);
}

ScanUDP::~ScanUDP()
{

}

bool ScanUDP::initSocket()
{
    m_ports.clear();
    for(int idx = 0; idx < 65536; ++idx)
        m_ports.append(idx);
    return true;
}

void ScanUDP::stopUDPScan()
{
    m_stop = false;
}

bool ScanUDP::beginUDPScan()
{
    if(!m_init)
    {
        int fromlen = sizeof(SOCKADDR_IN); int timeout = m_dwTimeout; m_init = true;
        int bread = setsockopt(m_sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
        if(bread == SOCKET_ERROR)
        {
            DoxLogger("setsockopt(SO_RCVTIMEO) failed;");
            exit(1);
        }
    }
    HANDLE handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)udpScanThread, this, 0, NULL);
    if(handle == INVALID_HANDLE_VALUE)
    {
        DoxLogger("创建线程失败");
        return false;
    }
    CloseHandle(handle);
    return true;
}

ulong ScanUDP::udpScanThread(void *param)
{
    ScanUDP *_udp = (ScanUDP *)param;
    for(int indx = 0; indx < _udp->m_ips.length(); ++indx)
    {
        ulong ip = _udp->m_ips[indx];
        for(int idx = 0; idx < _udp->m_ports.length(); ++idx)
        {
            SOCKADDR_IN addr; char buf[255] = { 0 };
            addr.sin_family = AF_INET;
            addr.sin_addr.S_un.S_addr = htonl(ip);
            addr.sin_port = htons(_udp->m_ports[idx]);
            int nServAddLen = sizeof(addr);
            if(sendto(_udp->m_sock, buf, 255, 0, (sockaddr *)&addr, nServAddLen) != SOCKET_ERROR)
            {
                if(_udp->m_func.pfnProgress)
                {
                    Object<IDoxPointer> pro(NIL);
                    pro->setLong(indx);
                    _udp->m_func.pfnProgress(pro);
                }
                if(_udp->m_func.pfnMessage)
                {
                    Object<IDoxPointer> ptr(NIL);
                    QString info = QS("主机[%1]已开启。").arg(inet_ntoa(addr.sin_addr));
                    ptr->setString(info); _udp->m_func.pfnMessage(ptr);
                    Sleep(50);
                }
                break;
            }
        }
    }
    return true;
}

void ScanUDP::setDesPort(const ULongArr &ports)
{
    if(ports.length() == 0) return;
    for(int idx = 0; idx < ports.length(); ++idx)
        m_ports.append(ports[idx]);
}

void ScanUDP::setSyntonyFunc(const DoxExtraFunc &pa)
{
    m_func = pa;
}

bool ScanUDP::setUDPScanIP(const QString &ip, ulong timeOut)
{
    m_ips.clear();
    ulong lip = inet_addr(ip.toLocal8Bit().constData());
    m_ips.append(lip); return true;
}

bool ScanUDP::setUDPScanIPs(const ULongArr &ips, ulong timeOut)
{
    m_ips.clear();
    for(int idx = 0; idx < ips.length(); ++idx)
        m_ips.append(ips[idx]);
    return true;
}

bool ScanUDP::setUDPScanIP(ulong sip, ulong eip, ulong timeOut)
{
    m_ips.clear();
    for(ulong ip = sip; ip <= eip; ip++)
        m_ips.append(ip);
    return true;
}

bool ScanUDP::setUDPScanIPs(const QStringList &ipss, ulong timeOut)
{
    m_ips.clear();
    for(int idx = 0; idx < ipss.length(); ++idx)
    {
        QString ip = ipss[idx];
        ulong lip = inet_addr(ip.toLocal8Bit().constData());
        m_ips.append(lip);
    }
    return true;
}

源程序下载地址:https://download.csdn.net/download/yangfahe1/10909507

示例程序运行方式:https://blog.csdn.net/yangfahe1/article/details/84028318