Skip to content

标题: 在CE 4.2上实现ping功能

CE 4.2不支持raw socket,因此移植BSD Socket、Winsock的ping实现到PDA上,这个 想法趁早放弃吧。我最初也是不信邪的,其实这种不信邪完全没道理,仅仅是个人发 傻。

进MSDN里搜了一番,发现CE 4.2虽然不支持raw socket,但直接提供了一批用于实现 ping的函数。我最终实践成功的方案如下:

include

pragma comment( lib, "iphlpapi.lib" )

/ * 发送ICMP Echo Request报文,等待ICMP Echo Reply报文。 * * CE不支持raw socket,被迫使用IcmpCreateFile()这类函数。 / static void ping ( unsigned int ip, FILE o, unsigned char str ) { HANDLE icmphandle = INVALID_HANDLE_VALUE; unsigned char buf = NULL; unsigned int buflen; / * 取自Windows平台的ping实现 */ unsigned char icmpdata[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69 }; DWORD n;

buflen  = sizeof( ICMP_ECHO_REPLY ) + sizeof( icmpdata );
buf     = ( unsigned char * )Calloc( buflen, 1 );
if ( INVALID_HANDLE_VALUE == ( icmphandle = IcmpCreateFile() ) )
{
    PrintWin32ErrorCLI( "IcmpCreateFile() failed", GetLastError() );
    goto ping_exit;
}
/*
 * 发送请求报文
 */
n       = IcmpSendEcho
(
    icmphandle,
    ip,
    &icmpdata,
    sizeof( icmpdata ),
    NULL,
    buf,
    buflen,
    timeout * 1000
);
if ( 0 == n )
{

if 0

    fprintf
    (
        stderr,
        "ip              = 0x%08X\n",
        ip
    );
    PrintWin32ErrorCLI( "IcmpSendEcho() failed", GetLastError() );

endif

    goto ping_exit;
}
if ( debug )
{
    fprintf
    (
        stderr,
        "n               = %u\n",
        n
    );
    outputBinary
    (
        stderr,
        buf,
        buflen
    );
}
if
(
    ( 1 == n )  &&
    ( ( ( ICMP_ECHO_REPLY * )buf )->Address == ip )
)
{
    fprintf
    (
        o,
        "%s\n",
        str
    );
}

ping_exit:

if ( INVALID_HANDLE_VALUE != icmphandle )
{
    IcmpCloseHandle( icmphandle );
    icmphandle  = INVALID_HANDLE_VALUE;
}
if ( NULL != buf )
{
    free( buf );
    buf         = NULL;
}
return;

} / end of ping /