标题: 在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 /