计网实验大作业_ping程序实现

ping 程序实现

1.软件使用说明

本软件由源码和可执行文件.exe构成,运行.exe后可以看到控制台界面和一行提示“请输入要ping的域名或ip地址:”,在其后输入以www开头的域名或点分十进制格式的ip地址后回车,就能够ping对应的域名或ip地址。对于要ping的域名,软件会ping所有经过DNS域名解析服务器根据主机名解析得到对应的IP地址,因为一个域名可能对应到多个服务器,所以解析到的ip地址不一定只有一个。

实现的功能包括:
(1) 可以指定ping的目标主机ip, 并且支持域名,如”www.baidu.com”。
(2) 每次发送4个ICMP回送请求报文,每个请求报文的数据大小为32B,发送超时和接收超时时间为1000ms。
(3) 对于发出的每个ICMP回送请求报文,若收到应答报文,显示每个应答报文的数据大小(B),源IP、序号、响应时间(ms);若发送超时或接收超时,显示“Request time out.”。
(4) 最后显示用户名和ping的统计信息,统计信息包括发出的请求报文个数、收到的应答报文个数、丢包个数和丢包率。

2.API和数据结构说明

引用的API:

API函数名API函数原型说明
WSAStartupint WSAAPI WSAStartup(In WORD wVersionRequested, Out LPWSADATA lpWSAData );初始化
WSACreateEventWSAEVENT WSAAPI WSACreateEvent(void);生成事件
GetCurrentProcessIdDWORD WINAPI GetCurrentProcessId( VOID );获取进程Id
WSASocketWSOCKET WSAAPI WSASocketW( In int af,In int type,In int protocol,In_opt LPWSAPROTOCOL_INFOW lpProtocolInfo,In GROUP g,In DWORD dwFlags);套接字
WSAEventSelectint WSAAPI WSAEventSelect( In SOCKET s, In_opt WSAEVENT hEventObject, In long lNetworkEvents );选择事件
WSACleanupint WSAAPI WSACleanup( void );清除内容
sendtoint WSAAPI sendto( In SOCKET s, In_reads_bytes(len) const char FAR * buf, In int len, In int flags, In_reads_bytes(tolen) const struct sockaddr FAR * to, In int tolen );发送数据包
WSAWaitForMultipleEventsDWORD WSAAPI WSAWaitForMultipleEvents( In DWORD cEvents, In_reads(cEvents) const WSAEVENT FAR * lphEvents, In BOOL fWaitAll, In DWORD dwTimeout, In BOOL fAlertable );等待事件
WSAEnumNetworkEventsint WSAAPI WSAEnumNetworkEvents( In SOCKET s, In WSAEVENT hEventObject, Out LPWSANETWORKEVENTS pNetworkEvents );联合网络事件
recvfromint WSAAPI recvfrom( In SOCKET s, Out_writes_bytes_to(len, return) __out_data_source(NETWORK) char FAR * buf, In int len, In int flags, Out_writes_bytes_to_opt(*fromlen, *fromlen) struct sockaddr FAR * from, Inout_opt int FAR * romlen );接收数据包
GetLocalTimeVOID WINAPI GetLocalTime( Out LPSYSTEMTIME lpSystemTime );获取本地时间
SystemTimeToFileTimeBOOL WINAPI SystemTimeToFileTime( In CONST SYSTEMTIME* lpSystemTime, Out LPFILETIME lpFileTime );系统时间转文件时间
gethostbynamestruct hostent FAR * WSAAPI gethostbyname( In_z const char FAR * name );获取主机信息
GetLastErrorDWORD WINAPI GetLastError( VOID );返回错误结果

定义的数据结构:

struct IPHeader
{
	BYTE m_byVerHLen; //4位版本+4位首部长度
	BYTE m_byTOS; //服务类型
	USHORT m_usTotalLen; //总长度
	USHORT m_usID; //标识
	USHORT m_usFlagFragOffset; //3位标志+13位片偏移
	BYTE m_byTTL; //TTL
	BYTE m_byProtocol; //协议
	USHORT m_usHChecksum; //首部检验和
	ULONG m_ulSrcIP; //源IP地址
	ULONG m_ulDestIP; //目的IP地址
};

struct ICMPHeader
{
	BYTE m_byType; //类型
	BYTE m_byCode; //代码
	USHORT m_usChecksum; //检验和 
	USHORT m_usID; //标识符
	USHORT m_usSeq; //序号
	ULONG m_ulTimeStamp; //时间戳(非标准ICMP头部)
};

struct PingReply
{
	USHORT m_usSeq; //响应序列号
	DWORD m_dwRoundTripTime;  //往返时间
	DWORD m_dwBytes;  //数据包大小
	DWORD m_dwTTL;  //生存时间
};

class ParseUrl //解析url
{
public:
	ParseUrl();    //构造函数
	~ParseUrl();   //析构函数
	BOOL Ping(DWORD dwDestIP, PingReply *pPingReply = NULL, DWORD dwTimeout = 1000); //设定超时时间
	BOOL Ping(char *szDestIP, PingReply *pPingReply = NULL, DWORD dwTimeout = 1000); //设定超时时间
private:
	BOOL PingCore(DWORD dwDestIP, PingReply *pPingReply, DWORD dwTimeout);
	USHORT CalCheckSum(USHORT *pBuffer, int nSize);  //校验和
	ULONG GetTickCountCalibrate();       
private:
	SOCKET m_sockRaw;
	WSAEVENT m_event;
	USHORT m_usCurrentProcID;
	char *m_szICMPData;
	BOOL m_bIsInitSucc;
private:
	static USHORT s_usPacketSeq;
}; 
3.软件功能流程图
Created with Raphaël 2.2.0 开始 输入是否是域名? 获取域名对应的所有ip地址 pingIp发送4次报文 初始化 初始化是否成功? 配置socket 构建ICMP包 发送ICMP报文 是否需要接收报文? 接收报文 是否是ICMP响应报文? 是否是当前进程发出的报文? 是否是本次请求的响应报文? 是否超时? Request Time Out 是否是最后一次报文? 是否是最后一个ip? 结束 显示统计信息 结束 输入是否是ip? yes no yes no yes no yes no yes no yes no yes no yes no yes no yes no
  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值