【TCP/IP】C語言實現Ping小程序

Ping程序一般用來測試一臺主機是否可達,該程序發送一份ICMP回顯請求報文給主機,并等待返回ICMP回顯 應答。愛掏網 - it200.com

一般來說,如果不能Ping到某主機,那么就不能Telnet或者FTP到那臺主機。愛掏網 - it200.com反過來,如果不能Telnet到某臺主機,那么通常可以用Ping程序來確定問題出在哪里。愛掏網 - it200.comPing程序還可以檢測出到這臺主機的往返時間,以表明該主機里我們有“多遠”。愛掏網 - it200.com大多數的TCP/IP實現都在內核中直接支持Ping服務器。愛掏網 - it200.com

?

ICMP回顯請求和回顯應答報文如下所示

?/****************************************************************/
/* ? ? ? ?類型(0或8)| ? ? ? ?代碼(0)| ? ? ? ? ? ?校驗和 ? ? ? ?|*/
/****************************************************************/
/* ? ? ? ? ? ? ? ?標識符 ? ? ? ? ? ?| ? ? ? ? ? ? ? ?序號 ? ? ? ?|*/
/****************************************************************/
/* ? ? ? ? ? ? ? ? ? ? ? ? ? ?選項數據 ? ? ? ? ? ? ? ? ? ? ? ? ? |*/
/****************************************************************/


定義ICMP報頭數據結構

typedef struct _ICMP_HEADER{
? ? BYTE nType;
? ? BYTE nCode;
? ? USHORT nCheckSum;
? ? USHORT nId;
? ? USHORT nSequence;
? ? UINT nTimeStamp;
}ICMP_HEADER,*PICMP_HEADER;


下面使用Socket實現Ping小程序。愛掏網 - it200.com

// PingSock.cpp : 定義控制臺應用程序的入口點。愛掏網 - it200.com
//
#include "stdafx.h"
#include
#pragma comment(lib,"ws2_32.lib")
#include


//定義默認緩沖區長度
#define DEF_BUF_SIZE 1024
#define IP_HEADER_SIZE 20
#define ICMP_HEADER_SIZE (sizeof(ICMP_HEADER))
#define ICMP_DATA_SIZE 32
#define ICMP_PACK_SIZE (ICMP_HEADER_SIZE + ICMP_DATA_SIZE)


typedef struct _ICMP_HEADER{
? ? BYTE nType;
? ? BYTE nCode;
? ? USHORT nCheckSum;
? ? USHORT nId;
? ? USHORT nSequence;
? ? UINT nTimeStamp;
}ICMP_HEADER,*PICMP_HEADER;
?
char szInfo[DEF_BUF_SIZE] = {0};


USHORT GetCheckSum(LPBYTE lpBuf, DWORD dwSize);
BOOL Ping(char* lpDestIp);


int _tmain(int argc, _TCHAR* argv[])
{
? ? char szDestIp[DEF_BUF_SIZE] = {0} ;
? ? while ( scanf ( "%s", szDestIp) )
? ? ? ? Ping ( szDestIp ) ;
? ? ?
? ? return 0;
}


USHORT GetCheckSum(LPBYTE lpBuf, DWORD dwSize)
{
? ? DWORD dwCheckSum = 0;
? ? USHORT* lpWord = (USHORT*)lpBuf;


? ? while( dwSize > 1)
? ? {
? ? ? ? dwCheckSum += *lpWord++;
? ? ? ? dwSize -= 2;
? ? }


? ? if(1 == dwSize)
? ? ? ? dwCheckSum += *((USHORT*)lpBuf);


? ? dwCheckSum = ( dwCheckSum >> 16) + ( dwCheckSum & 0xffff);
? ? return (USHORT)(~dwCheckSum);
}


BOOL Ping(char* lpDestIp)
{
? ? SOCKADDR_IN DestAddr;
? ? DestAddr.sin_family = AF_INET;
? ? DestAddr.sin_addr.S_un.S_addr = inet_addr(lpDestIp);
? ? DestAddr.sin_port = htons(0);


? ? //創建ICMP請求包
? ? char ICMPPack[ICMP_PACK_SIZE] = {0};
? ? PICMP_HEADER pICMPHeader = (PICMP_HEADER)ICMPPack;
? ? pICMPHeader->nType = 8;
? ? pICMPHeader->nCode = 0;
? ? pICMPHeader->nId = (USHORT)::GetCurrentProcessId();
? ? pICMPHeader->nCheckSum = 0;
? ? pICMPHeader->nTimeStamp = 0;
? ? memset(&(ICMPPack[ICMP_HEADER_SIZE]),'E',ICMP_DATA_SIZE);


? ? //初始化WinSock
? ? WORD wVersionRequested = MAKEWORD(2,2);
? ? WSADATA wsaData;
? ? if(WSAStartup(wVersionRequested,&wsaData) != 0)
? ? {
? ? ? ? return FALSE;
? ? }


? ? //創建初始套接字
? ? SOCKET RawSock = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
? ? if(INVALID_SOCKET == RawSock)
? ? {
? ? ? ? printf("create raw socket error\n");
? ? ? ? return FALSE;
? ? }


? ? int nTime = 1000;
? ? int nRet = ::setsockopt( RawSock, SOL_SOCKET, SO_RCVTIMEO,(char*)(&nTime),sizeof(nTime));


? ? char szRecvBuf [ DEF_BUF_SIZE] ;
? ? SOCKADDR_IN ? ?SourSockAddr ;


? ? for(int i = 0; i ? ? {
? ? ? ? pICMPHeader->nCheckSum = 0;
? ? ? ? pICMPHeader->nTimeStamp = ::GetTickCount();
? ? ? ? pICMPHeader->nSequence = i;


? ? ? ? pICMPHeader->nCheckSum = GetCheckSum ( (LPBYTE)ICMPPack, ICMP_PACK_SIZE ) ;


? ? ? ? int nRet = ::sendto( RawSock, ICMPPack, ICMP_PACK_SIZE, 0, (SOCKADDR*)&DestAddr, sizeof(DestAddr));
? ? ? ? if ( nRet == SOCKET_ERROR )
? ? ? ? {
? ? ? ? ? ? printf ( "sendto error!\n" ) ;
? ? ? ? ? ? return FALSE ;
? ? ? ? }


? ? ? ? // 接收ICMP響應
? ? ? ? int nLen = sizeof(SourSockAddr) ;
? ? ? ? nRet = ::recvfrom ( RawSock, szRecvBuf, DEF_BUF_SIZE,0,(SOCKADDR*)&SourSockAddr, &nLen ) ;
? ? ? ? if ( nRet == SOCKET_ERROR )
? ? ? ? {
? ? ? ? ? ? if ( ::WSAGetLastError() == WSAETIMEDOUT )
? ? ? ? ? ? {
? ? ? ? ? ? ? ? printf ( "Request Timeout\n" ) ;
? ? ? ? ? ? ? ? continue ;
? ? ? ? ? ? }
? ? ? ? ? ? else
? ? ? ? ? ? {
? ? ? ? ? ? ? ? printf ( "recvfrom error!\n" ) ;
? ? ? ? ? ? ? ? return FALSE ;
? ? ? ? ? ? }
? ? ? ? }


? ? ? ? int nTime = ::GetTickCount() - pICMPHeader->nTimeStamp ;


? ? ? ? int nRealSize = nRet - IP_HEADER_SIZE - ICMP_HEADER_SIZE ;
? ? ? ? if ( nRealSize ? ? ? ? {
? ? ? ? ? ? printf ( "To less recv bytes!\n" ) ;
? ? ? ? ? ? continue ;
? ? ? ? }


? ? ? ? // 檢測是否當前所發出的ICMP響應包
? ? ? ? PICMP_HEADER pRecvHeader = (PICMP_HEADER)(szRecvBuf+IP_HEADER_SIZE) ;
? ? ? ? if ( pRecvHeader->nType != 0 )
? ? ? ? {
? ? ? ? ? ? printf ( "Not ICMP respond type!\n" ) ;
? ? ? ? ? ? return FALSE ;
? ? ? ? }


? ? ? ? if ( pRecvHeader->nId != ::GetCurrentProcessId () )
? ? ? ? {
? ? ? ? ? ? printf ( "not valid id!\n" ) ;
? ? ? ? ? ? return FALSE ;
? ? ? ? }


? ? ? ? printf ( "%d bytes replay from %s : bytes=%d time=%dms\n", \
? ? ? ? ? ? nRet, inet_ntoa(SourSockAddr.sin_addr), nRealSize, nTime ) ;


? ? ? ? ::Sleep ( 1000 ) ;
? ? }


? ? closesocket ( RawSock ) ;
? ? WSACleanup () ;


? ? return TRUE ;
}


聲明:所有內容來自互聯網搜索結果,不保證100%準確性,僅供參考。如若本站內容侵犯了原著者的合法權益,可聯系我們進行處理。
發表評論
更多 網友評論0 條評論)
暫無評論

返回頂部

主站蜘蛛池模板: 99久久婷婷国产综合精品| 国产乱妇乱子在线播放视频| 亚洲高清偷拍一区二区三区| yellow2019电影在线高清观看| 色135综合网| 日本www.色| 国产一区二区精品久久岳| 久久婷婷五月综合97色一本一本 | 久久久久亚洲精品天堂| 高清欧美一区二区免费影视| 日韩精品视频美在线精品视频| 国产精品99re| 亚州人成网在线播放| 黄色毛片小视频| 日日干夜夜操s8| 国产精品亚洲欧美云霸高清| 亚洲日本在线电影| 114级毛片免费观看| 欧美亚洲日本另类人人澡gogo| 国产精品免费视频网站| 亚洲aⅴ男人的天堂在线观看| 91丁香亚洲综合社区| 日本成人免费在线| 向日葵app看片视频| …久久精品99久久香蕉国产| 男人添女人30分钟免费| 国产麻豆视频免费观看| 亚洲国产精品久久网午夜| 久草视频免费在线| 日本一本二本免费播放视频| 向日葵app下载视频免费| videsgratis欧美另类| 污视频免费看网站| 国产激情一区二区三区四区| 久久国产精品99精品国产| 肥臀熟女一区二区三区| 好大好深别停视频视频| 亚洲日韩精品欧美一区二区| 黄色网址免费在线| 成人午夜电影在线| 亚洲AV成人片无码网站|