首页
社区
课程
招聘
[求助]我想写一个函数,参数为ip地址,用来探测此ip主机是否在线
发表于: 2014-7-29 11:16 4469

[求助]我想写一个函数,参数为ip地址,用来探测此ip主机是否在线

2014-7-29 11:16
4469
【求助】我想写一个函数,参数为ip地址,用来探测此ip主机是否在线
入参ip地址
返回值是简单的true或者false就可以
谁有可用的代码能帮下么,没什么思路

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 29
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
如果能直接调用系统的ping命令实现也可以,可要怎样实现呢
2014-7-29 11:41
0
雪    币: 2153
活跃值: (740)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
3
隐藏运行ping,创建进程时把输出输入用管道重定向,读管道数据即可

typedef struct _STARTUPINFOA {
    DWORD   cb;
    LPSTR   lpReserved;
    LPSTR   lpDesktop;
    LPSTR   lpTitle;
    DWORD   dwX;
    DWORD   dwY;
    DWORD   dwXSize;
    DWORD   dwYSize;
    DWORD   dwXCountChars;
    DWORD   dwYCountChars;
    DWORD   dwFillAttribute;
    DWORD   dwFlags;
    WORD    wShowWindow;
    WORD    cbReserved2;
    LPBYTE  lpReserved2;
    HANDLE  hStdInput;//here
    HANDLE  hStdOutput;//here
    HANDLE  hStdError;
} STARTUPINFOA, *LPSTARTUPINFOA;

直接用API也行,具体啥名字忘了,可以查到
2014-7-29 11:46
0
雪    币: 2153
活跃值: (740)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
4
好像是用iphlpapi库里面的函数
看到里面有有一些导出函数是有关ICMP的
2014-7-29 11:52
0
雪    币: 60
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
createpipe
2014-7-29 13:18
0
雪    币: 4751
活跃值: (1783)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
ping效果不好  很多主机防ping   建议用半开扫描探测技术(syn刺探)
2014-7-29 13:36
0
雪    币: 121
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
///////////////////////////////////////////
// ping.cpp文件

#include "../common/initsock.h"
#include "../common/protoinfo.h"
#include "../common/comm.h"

#include <stdio.h>

CInitSock theSock;

typedef struct icmp_hdr
{
    unsigned char   icmp_type;                // 消息类型
    unsigned char   icmp_code;                // 代码
    unsigned short  icmp_checksum;        // 校验和

        // 下面是回显头
    unsigned short  icmp_id;                // 用来惟一标识此请求的ID号,通常设置为进程ID
    unsigned short  icmp_sequence;        // 序列号
    unsigned long   icmp_timestamp; // 时间戳
} ICMP_HDR, *PICMP_HDR;

int main()
{
        // 目的IP地址,即要Ping的IP地址
        char szDestIp[] = "119.147.15.13";        // 127.0.0.1

        // 创建原始套节字
        SOCKET sRaw = ::socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);

        // 设置接收超时
        SetTimeout(sRaw, 1000, TRUE);

        // 设置目的地址
        SOCKADDR_IN dest;
        dest.sin_family = AF_INET;
        dest.sin_port = htons(0);
        dest.sin_addr.S_un.S_addr = inet_addr(szDestIp);

        // 创建ICMP封包
        char buff[sizeof(ICMP_HDR) + 32];
        ICMP_HDR* pIcmp = (ICMP_HDR*)buff;

        // 填写ICMP封包数据,请求一个ICMP回显
        pIcmp->icmp_type = 8;       
        pIcmp->icmp_code = 0;
        pIcmp->icmp_id = (USHORT)::GetCurrentProcessId();
        pIcmp->icmp_checksum = 0;
        pIcmp->icmp_sequence = 0;

        // 填充数据部分,可以为任意
        memset(&buff[sizeof(ICMP_HDR)], 'E', 32);
       
        // 开始发送和接收ICMP封包
        USHORT        nSeq = 0;
        char recvBuf[1024];
        SOCKADDR_IN from;
        int nLen = sizeof(from);
        while(TRUE)
        {
                static int nCount = 0;
                int nRet;

                // ping次数
                if(nCount++ == 1000)
                        break;

                pIcmp->icmp_checksum = 0;
                pIcmp->icmp_timestamp = ::GetTickCount();
                pIcmp->icmp_sequence = nSeq++;
                pIcmp->icmp_checksum = checksum((USHORT*)buff, sizeof(ICMP_HDR) + 32);
                nRet = ::sendto(sRaw, buff, sizeof(ICMP_HDR) + 32, 0, (SOCKADDR *)&dest, sizeof(dest));
                if(nRet == SOCKET_ERROR)
                {
                        printf(" sendto() failed: %d /n", ::WSAGetLastError());
                        return -1;
                }
                nRet = ::recvfrom(sRaw, recvBuf, 1024, 0, (sockaddr*)&from, &nLen);
                if(nRet == SOCKET_ERROR)
                {
                        if(::WSAGetLastError() == WSAETIMEDOUT)
                        {
                                printf(" timed out/n");
                                continue;
                        }
                        printf(" recvfrom() failed: %d/n", ::WSAGetLastError());
                        return -1;
                }

                // 下面开始解析接收到的ICMP封包
                int nTick = ::GetTickCount();
                if(nRet < sizeof(IPHeader) + sizeof(ICMP_HDR))
                {
                        printf(" Too few bytes from %s /n", ::inet_ntoa(from.sin_addr));
                }

                // 接收到的数据中包含IP头,IP头大小为20个字节,所以加20得到ICMP头
                // (ICMP_HDR*)(recvBuf + sizeof(IPHeader));
                ICMP_HDR* pRecvIcmp = (ICMP_HDR*)(recvBuf + 20);
                if(pRecvIcmp->icmp_type != 0)        // 回显
                {
                        printf(" nonecho type %d recvd /n", pRecvIcmp->icmp_type);
                        return -1;
                }

                if(pRecvIcmp->icmp_id != ::GetCurrentProcessId())
                {
                        printf(" someone else's packet! /n");
                        return -1;
                }
               
                printf("从 %s 返回 %d 字节:", inet_ntoa(from.sin_addr),nRet);
                printf(" 数据包序列号 = %d. /t", pRecvIcmp->icmp_sequence);
                printf(" 延时大小: %d ms", nTick - pRecvIcmp->icmp_timestamp);
                printf(" /n");

                // 每一秒发送一次就行了
                ::Sleep(1000);
        }
        return 0;
}
2014-7-29 13:42
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
8
Ping最简单,但是可能会被对方限制,代码也不用楼上那么麻烦
IcmpCreateFile/IcmpSendEcho/IcmpCloseHandle三个函数,不超过10行代码就可以搞定
2014-7-30 12:03
0
雪    币: 29
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
谢谢,用这3个函数实现了
2014-7-30 14:27
0
游客
登录 | 注册 方可回帖
返回
//