SimplePing 的实现原理
ping 使用的是ICMP协议,它发送icmp回送请求消息给目的主机。ICMP协议规定:目的主机必须返回ICMP回送应答消息给源主机。如果源主机在一定时间内收到应答,则认为主机可达。
ping 是通过网络层的 IP 协议发送 ICMP 协议的数据包,然后等待目标回传 ICMP 数据包,通过时间和成功响应的次数估算丢包率和网络时延。但是SimplePing并没有告诉我们从发包到收包具体花了多久,所以需要我们自己去实现
其实 ping 并不能完全代表你能不能连接上那个 host,像 zhihu.com 就封掉了 ICMP(ping 就没办法工作了,一直提示超时),但是通过浏览器(HTTP)还是能打开知乎的。
SimplePing 的使用步骤
- 利用 HostName 创建 SimplePing
- 指定 IP 地址类型
- 设置 delegate,用于接收回调信息
- 开始 ping
self.pinger = [[SimplePing alloc] initWithHostName:hostName];
self.pinger.addressStyle = SimplePingAddressStyleAny;
self.pinger.delegate = self;
[self.pinger start];
SimplePingDelegate方法介绍
解析 HostName 拿到 ip 地址之后,发送封包
- (void)simplePing:(SimplePing *)pinger didStartWithAddress:(NSData *)address
{
NSLog(@"pinging %@", displayAddressForAddress(address));
[self sendPing];
}
功能启动失败
- (void)simplePing:(SimplePing *)pinger didFailWithError:(NSError *)error
{
NSLog(@"failed: %@", shortErrorFromError(error));
[self stop];
}
成功发送封包
- (void)simplePing:(SimplePing *)pinger didSendPacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber
{
NSLog(@"#%u sent", sequenceNumber);
}
发送封包失败
- (void)simplePing:(SimplePing *)pinger didFailToSendPacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber error:(NSError *)error
{
NSLog(@"#%u send failed: %@", sequenceNumber,shortErrorFromError(error));
ping 发送封包之后收到响应
- (void)simplePing:(SimplePing *)pinger didReceivePingResponsePacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber
{
NSLog(@"#%u received, size=%zu", sequenceNumber, packet.length);
}
接收响应封包发生异常
- (void)simplePing:(SimplePing *)pinger didReceiveUnexpectedPacket:(NSData *)packet
{
NSLog(@"unexpected packet, size=%zu", packet.length);
}
iOS ping - SimplePing 源码解读
同一时间ping多个IP地址
测网速
#include <ifaddrs.h>
如何获取当前实时的网速呢?
那就是使用Uinx结构体;ifaddrs这个结构体在头文件ifaddrs.h中定义,能获取所有网卡的数据。
只要读取上一秒网卡中的流量使用情况,再读取当前的流量使用情况,就可以计算出网速。