在 iOS 平台实现Ping 和 traceroute

ICMP协议实战指南:从ping原理到企业级策略配置 ICMP(Internet控制报文协议)是IP网络中用于传递错误信息和诊断反馈的核心协议,虽不承载业务数据,却在链路连通性验证、路径探测、MTU发现及故障定位中发挥不可替代作用。其无连接、无端口、低开销的设计使其成为穿透防火墙的底层信标,支撑ping、traceroute、pathping等关键工具的运行逻辑。深入理解ICMP Type/Code分类(如Type 3 Code 4用于PMTUD、Type 11驱动路径追踪)可精准识别‘ping通但业务不通’类问题,避免将MTU不匹配误判为带宽不足,或将ICM 阅读详情

ping 命令

Ping是为了测试另一台主机是否可达,现在已经成为一种常用的网络状态检查工具。

常见的ping命令:

/**** 往目的追击发送固定包数 ****/
ping -c 3 www.baidu.com   // ping百度发送3个包

/**** 设置两次发包之间的等待时间 ****/
ping -i 5 www.baidu.com   // 两包之间的时间间隔为5s
ping -i 0.1 www.baidu.com // 两包之间的时间间隔为0.1s

/**** 检查本地网络接口是否已经启动并正在运行  ****/
ping 127.0.0.1  (linux: ping 0) 
ping localhost 

/**** 超级用户可以利用 -f 几秒钟发送数十万个包给主服务造成压力 *****/
sudo ping -f www.baidu.com 

/**** 让电脑发出蜂鸣声: 响应包到达目时,会发出声音  ****/
ping -a www.baidu.com 

/**** 只打印ping的汇总结果  ****/
ping -c 5 -q www.baidu.com

/**** 修改ping包(icmp包)的大小 ****/
ping -s 100 -c 5 www.baidu.com




示例:

macdeiMac:PhoneNetSDK ethan$ ping www.baidu.com

PING www.a.shifen.com (61.135.169.121): 56 data bytes
64 bytes from 61.135.169.121: icmp_seq=0 ttl=49 time=32.559 ms
64 bytes from 61.135.169.121: icmp_seq=1 ttl=49 time=32.413 ms
64 bytes from 61.135.169.121: icmp_seq=2 ttl=49 time=32.489 ms
^C
--- www.a.shifen.com ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 32.413/32.487/32.559/0.060 ms
macdeiMac:PhoneNetSDK ethan$ 

分析以上结果:

  • 发送端信息

    • www.a.shifen.com (61.135.169.121): 对域名做了自动DNS解析
    • 56 data bytes: 向该主机发送大小是56字节的数据包。
  • 主机响应的信息

    • icmp_seq: 响应包的序列号。
    • ttl: ip数据报的ttl值。
    • time:请求往返耗时。
    • 64 bytes:响应数据包的大小是64个字节。
  • 统计总结信息

    • 0.0% packet loss: 总共发了3个包丢包率是0%
    • min/avg/max = 32.413/32.487/32.559:最小/平均/最大往返时间32.413/32.487/32.559

TTL(Time to live): IP数据报的生存时间,单位是hop(跳)。比如64,每过一个路由器就把该值减1,如果减到0 就表示路由已经太长了仍然找不到目的主机的网络,就丢弃该包。

问题:在发包时,为什么发送的是56字节的包,主机响应的却是64字节的包? 在这里的56和64是同一个概念吗?

icmp

互联网控制消息协议(英语:Internet Control Message Protocol,缩写:ICMP)是互联网协议族的核心协议之一。它是TCP/IP协议族的一个子协议,它用于TCP/IP网络中发送控制消息,提供可能发生在通信环境中的各种问题反馈,通过这些信息,使管理者可以对所发生的问题作出诊断,然后采取适当的措施解决。

控制消息有:目的不可达下次,超时信息,重定向消息,时间戳请求和时间戳响应消息,回显请求和回显应答消息。

ICMP [1]依靠IP來完成它的任务,它是IP的主要部分。它与传输协议(如TCP和UDP)显著不同:它一般不用于在两点间传输数据。它通常不由网络程序直接使用,除了ping和traceroute这两个特別的例子。 IPv4中的ICMP被称作ICMPv4,IPv6中的ICMP则被称作ICMPv6。

icmp技术细节

CMP是在RFC 792中定义的互联网协议族之一。通常用于返回的错误信息或是分析路由。ICMP错误消息总是包括了源数据并返回给发送者。 ICMP错误消息的例子之一是TTL值过期。每个路由器在转发数据报的时候都会把IP包头中的TTL值减1。如果TTL值为0,“TTL在传输中过期”的消息将会回报给源地址。 每个ICMP消息都是直接封裝在一个IP数据包中的,因此,和UDP一样,ICMP是不可靠的。

虽然ICMP是包含在IP数据包中的,但是对ICMP消息通常会特殊处理,会和一般IP数据包的处理不同,而不是作为IP的一个子协议来处理。在很多时候,需要去查看ICMP消息的內容,然后发送过当的错误消息到那个原來产生IP数据包的程序,即那个导致ICMP信息被传送的IP数据包。

很多常用的工具是基于ICMP消息的。traceroute是通过发送包含有特殊的TTL的包,然后接收ICMP超超消息和目标不可达消息來实现的。ping则是用ICMP的”Echo request”(类别代码:8)和”Echo reply”(类别代码:0)消息來实现的。

icmp报文结构
报头

ICMP报头从IP报头的第160位开始(ip首部20字节)

  • Type: ICMP的类型,标识生成的错误报文
  • Code: 进一步割分ICMP的类型,该字段用来查找产生错误的原因;例如ICMP的目标不可达类型可以把这个位设置为1-15等来表示不同的意思。
  • Checksum : 校验码部分,这个字段包含有从ICMP报头和数据部分计算得来,用于检查错误的数据,其中此校验码字段的值视为0
  • ID :这个字段包含了ID值,在Echo Reply类型的消息中要返回这个字段
  • Sequence : 这个字段包含一个序号,同样要在Echo Reply类型的消息中要返回这个字段
填充数据

填充的数据紧接在ICMP报头的后面(以8位为一组):

  • Linux的ping工具填充的ICMP除了8个8位元组的报头以外,默认情况下还另外填充数据使得总大小位64字节。
  • Windows的ping.exe填充的ICMP除了8个8位元组的报头以外,默认情况下还另外填充数据使得总大小位40字节。

ping

ping实现原理

Ping是为了测试另一台主机是否可达,现在已经成为一种常用的网络状态检查工具。该程序发送一份 ICMP回显请求报文给远程主机,并等待返回 ICMP回显应答。

ping 使用的是ICMP协议,它发送icmp回送请求消息给目的主机。ICMP协议规定:目的主机必须返回ICMP回送应答消息给源主机。如果源主机在一定时间内收到应答,则认为主机可达。大多数的 TCP/IP 实现都在内核中直接支持Ping服务器,ICMP回显请求和回显应答报文如下图所示。

image

ping的原理:

ping的原理是用类型码为8的ICMP发请求,收到请求的主机则用类型码为0的ICMP回应。通过计算ICMP应答报文数量和与接受与发送报文之间的时间差,判断当前的网络状态。这个往返时间的计算方法是:ping命令在发送ICMP报文时将当前的时间值存储在ICMP报文中发出,当应答报文返回时,使用当前时间值减去存放在ICMP报文数据中存放发送请求的时间值来计算往返时间。ping返回接收到的数据报文字节大小、TTL值以及往返时间。

利用wireshark查看ping

我在命令行中ping www.baidu.com 以下是显示结果:

image

image

如上图所示,icmp包的type是8 , 是request请求; icmp的包type是0 ,是reply.

计算机网络基础知识

TCP/IP协议栈与数据包封装

OSI七层模型以及TCP/IP模型:

两台计算机通过TCP/IP的通信过程如下:

传输层及其以下的机制由内核提供,应用层由用户进程提供,应用程序对通讯数据的含义进行解释,而传输层及其以下处理通讯的细节,将数据从一台计算机通过一定的路径发送到另一台计算机。应用层数据通过协议栈发到网络上时,每层协议都要加上一个数据首部(header),称为封装(Encapsulation)。

TCP/IP数据包的封装:

目的主机收到数据包后,经过各层协议栈最后到达应用程序。

以太网驱动程序首先根据以太网首部中的“上层协议”字段确定该数据帧的有效载荷是IP、ARP还是RARP协议的数据报,然后交给相应的协议处理。假如是IP数据报,IP协议再根据IP首部中的“上层协议”字段确定该数据报的有效载荷是TCP、UDP、ICMP还是IGMP,然后交给相应的协议处理。假如是TCP段或UDP段,TCP或UDP协议再根据TCP首部或UDP首部的“端口号”字段确定应该将应用层数据交给哪个用户进程。IP地址是标识网络中不同主机的地址,而端口号就是同一台主机上标识不同进程的地址,IP地址和端口号合起来标识网络中唯一的进程。

注意,虽然IP、ARP和RARP数据报都需要以太网驱动程序来封装成帧,但是从功能上划分,ARP和RARP属于链路层,IP属于网络层。虽然ICMP、IGMP、TCP、UDP的数据都需要IP协议来封装成数据报,但是从功能上划分,ICMP、IGMP与IP同属于网络层,TCP和UDP属于传输层。

IP数据报格式

IPv4数据包格式如下:

关于首部长度:

根据IP数据报,判断当前包是否是IPv4


version占4位,首部长度占4位,version = 4(IPv4), ipheader=20.
由于首部长度是以4字节为单位的-> version: 0100 ; 首部长度:0101

获取version:  0100 0101 & 0xFO(11110000) = 01000000 = 0x40
获取首部长度:  0100 0101 & 0x0F(00001111) = 0000 0101 = 5个4字节 = 20 Byte

ping实现(c++&oc)

技术预研与构思

根据ping的结果,我们需要解决以下问题:

macdeiMac:PhoneNetSDK ethan$ ping www.baidu.com

PING www.a.shifen.com (61.135.169.121): 56 data bytes
64 bytes from 61.135.169.121: icmp_seq=0 ttl=49 time=32.559 ms
64 bytes from 61.135.169.121: icmp_seq=1 ttl=49 time=32.413 ms
64 bytes from 61.135.169.121: icmp_seq=2 ttl=49 time=32.489 ms
^C
--- www.a.shifen.com ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 32.413/32.487/32.559/0.060 ms
macdeiMac:PhoneNetSDK ethan$ 
  • DNS解析(域名->ip)
  • 本地终端接收到的每个icmp包来自哪个主机
  • icmp_seq
  • ttl
  • time

以上问题解决方案如下:

  • DNS解析: socket支持
  • 本地终端接收到的每个icmp包来自哪个主机: ip包中的source
  • icmp_seq: icmp包中的 sequence number
  • ttl: ip包中的Time to live
  • time: 发送包和接收到包时的时间差
具体实现

IP包定义:

typedef struct PNetIPHeader {
    uint8_t versionAndHeaderLength;
    uint8_t differentiatedServices;
    uint16_t totalLength;
    uint16_t identification;
    uint16_t flagsAndFragmentOffset;
    uint8_t timeToLive;
    uint8_t protocol;
    uint16_t headerChecksum;
    uint8_t sourceAddress[4];
    uint8_t destinationAddress[4];
    // options...
    // data...
}PNetIPHeader;

ICMP包定义:

/*
 use linux style . totals 64B
 */
typedef struct UICMPPacket
{
    uint8_t type;
    uint8_t code;
    uint16_t checksum;
    uint16_t identifier;
    uint16_t seq;
    char fills[56];  // data
}UICMPPacket;

构造ICMP包:

+ (UICMPPacket *)constructPacketWithSeq:(uint16_t)seq andIdentifier:(uint16_t)identifier
{
    UICMPPacket *packet = (UICMPPacket *)malloc(sizeof(UICMPPacket));
    packet->type  = ENU_U_ICMPType_EchoRequest;
    packet->code = 0;
    packet->checksum = 0;
    packet->identifier = OSSwapHostToBigInt16(identifier);
    packet->seq = OSSwapHostToBigInt16(seq);
    memset(packet->fills, 65, 56);
    packet->checksum = [self in_cksumWithBuffer:packet andSize:sizeof(UICMPPacket)];
    return packet;
}

发送icmp包:

 UICMPPacket *packet = [PhoneNetDiagnosisHelper constructPacketWithSeq:index andIdentifier:identifier];
        _sendDate = [NSDate date];
        ssize_t sent = sendto(socket_client, packet, sizeof(UICMPPacket), 0, (struct sockaddr *)&remote_addr, (socklen_t)sizeof(struct sockaddr));
        if (sent < 0) {
            log4cplus_warn("PhoneNetPing", "ping %s , send icmp packet error..\n",[self.host UTF8String]);
        }

接收icmp包:

 size_t bytesRead = recvfrom(socket_client, buffer, 65535, 0, (struct sockaddr *)&ret_addr, &addrLen);
  if ((int)bytesRead < 0) {
            [self reporterPingResWithSorceIp:self.host ttl:0 timeMillSecond:0 seq:0 icmpId:0 dataSize:0 pingStatus:PhoneNetPingStatusDidTimeout];
            res = YES;
        }else if(bytesRead == 0){
            log4cplus_warn("PhoneNetPing", "ping %s , receive icmp packet error , bytesRead=0",[self.host UTF8String]);
        }else{
            
            if ([PhoneNetDiagnosisHelper isValidPingResponseWithBuffer:(char *)buffer len:(int)bytesRead]) {
                
                UICMPPacket *icmpPtr = (UICMPPacket *)[PhoneNetDiagnosisHelper icmpInpacket:(char *)buffer andLen:(int)bytesRead];
                
                int seq = OSSwapBigToHostInt16(icmpPtr->seq);
                
                NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:_sendDate];
                
                int ttl = ((PNetIPHeader *)buffer)->timeToLive;
                int size = (int)(bytesRead-sizeof(PNetIPHeader));
                NSString *sorceIp = self.host;
                
                
//                NSLog(@"PhoneNetPing, ping %@ , receive icmp packet..\n",self.host );
                [self reporterPingResWithSorceIp:sorceIp  ttl:ttl timeMillSecond:duration*1000 seq:seq icmpId:OSSwapBigToHostInt16(icmpPtr->identifier) dataSize:size pingStatus:PhoneNetPingStatusDidReceivePacket];
                res = YES;
            }

从接收到的buffer中分离icmp包:

/* 从 ipv4 数据包中解析出icmp */
+ (char *)icmpInpacket:(char *)packet andLen:(int)len
{
    if (len < (sizeof(PNetIPHeader) + sizeof(UICMPPacket))) {
        return NULL;
    }
    const struct PNetIPHeader *ipPtr = (const PNetIPHeader *)packet;
    if ((ipPtr->versionAndHeaderLength & 0xF0) != 0x40 // IPv4
        ||
        ipPtr->protocol != 1) { //ICMP
        return NULL;
    }
    size_t ipHeaderLength = (ipPtr->versionAndHeaderLength & 0x0F) * sizeof(uint32_t);
    
    if (len < ipHeaderLength + sizeof(UICMPPacket)) {
        return NULL;
    }
    
    return (char *)packet + ipHeaderLength;
}

校验接收到的icmp包:

+ (BOOL)isValidPingResponseWithBuffer:(char *)buffer len:(int)len
{
    UICMPPacket *icmpPtr = (UICMPPacket *)[self icmpInpacket:buffer andLen:len];
    if (icmpPtr == NULL) {
        return NO;
    }
    uint16_t receivedChecksum = icmpPtr->checksum;
    icmpPtr->checksum = 0;
    uint16_t calculatedChecksum = [self in_cksumWithBuffer:icmpPtr andSize:len-((char*)icmpPtr - buffer)];
    
    return receivedChecksum == calculatedChecksum &&
    icmpPtr->type == ENU_U_ICMPType_EchoReplay &&
    icmpPtr->code == 0 &&
    OSSwapBigToHostInt16(icmpPtr->identifier)>=KPingIcmpIdBeginNum;;
}

TCP ping

当有些服务器禁ping时,可以选择TCP ping。

TCP ping原理

通过和目的主机及其端口建立TCP连接的方式计算其连接耗时。

traceroute

traceroute命令

/**** 设置每个路由发送的包数 ****/
traceroute -q 5 baidu.com

/**** 设置最大路由跳数 ****/
traceroute -m 5 baidu.com

/**** 不做DNS解析 ****/
traceroute -n baidu.com

/**** 绕过路由表直接发送到目的治具 ****/
traceroute -r baidu.com

/**** 使用ICMP包取代UDP包 ****/
traceroute -I baidu.com

traceroute原理

tacceroute是利用增加存活时间(TTL)值来实现功能的。每当一个icmp包经过一个路由器时,其存活时间值就会减1,当其存活时间为0时,路由器便会取消包发送,并发送一个ICMP TTL封包给原封包发出者。

traceroute过程

主叫方首先发出TTL = 1 的数据包,第一个路由器将 TTL 减1得0后就不再继续转发此数据包,而是返回一个ICMP超时报文,主叫方从超时报文中即可提取出数据包所经过的第一个路由器的地址。然后又发出一个TTL=2的ICMP数据包,可获得第二个路由器的地址,依次增加TTL便获取了沿途所有路由器位地址。

需要注意的是,并不是所有路由器都会如实返回ICMP超时报文。出于安全性考虑,大多数防火墙以及启动了防火墙功能的路由器缺省配置为不返回各种ICMP报文,其路由器或交换机也可被管理员主动修改配置变为不返回ICMP报文。因此Traceroute程序不一定能拿全所有沿途路由器地址。所以当某个TTL值的数据包得不到响应是,并不能停止这一追踪过程,程序仍然会把TTL递增而发出下一个数据包。一直达到预设或用于参数制定的追踪限制时才结束追踪。

依据上述原理,利用了UDP数据包的Traceroute程序在数据包到达真正的目的主机时,就可能因为该主机没有提供UDP服务而简单将数据包丢弃,并不返回任何信息。为了解决这个问题,Traceroute故意使用了一个大于30000的端口号,因UDP协议规定端口号必须小于30000,所以目标主机收到数据包后唯一能做的事就是返回一个"端口不可达"的ICMP报文,于是主叫方就将端口不可达报文当做跟踪结束标志。

利用wireshark查看traceroute

我在命令行中traceroute www.baidu.com 以下是显示结果:

image

如上图所示,UDP请求,第一个请求的端口是33435 , 接下来的UDP请求,端口会递增。

当到达目的地址时,目的地址会replay类型为3的包.

image

如上图所示,是路由器返回的ICMP包,type是11。

UDP traceroute的实现

发送udp包,接收ip+icmp包,过滤route ip计算时间。

https://github.com/mediaios/net-diagnosis/tree/master/PhoneNetSDK/PhoneNetSDK/udptracert

UDP traceroute存在的问题

使用 UDP 的 traceroute,失败还是比较常见的。这常常是由于,在运营商的路由器上,UDP 与 ICMP 的待遇大不相同。为了利于 troubleshooting,ICMP 的request 和 replay 是不会封的,而 UDP 则不同。UDP 常被用来做网络攻击,因为 UDP 无需连接,因而没有任何状态约束它,比较方便攻击者伪造源 IP、伪造目的端口发送任意多的 UDP 包,长度自定义。所以运营商为安全考虑,对于 UDP 端口常常采用白名单 ACL,就是只有 ACL 允许的端口才可以通过,没有明确允许的则统统丢弃。比如允许 DNS/DHCP/SNMP 等。

icmp traceroute

发送icmp包,类型为8,每个路由返回的icmp包类型是11的超时包,当到达目的地址时,目的地址会replay类型为0的包

icmp traceroute的实现

https://github.com/mediaios/net-diagnosis/tree/master/PhoneNetSDK/PhoneNetSDK/utracert

net-diagnosis(ios平台下网络诊断SDK)

net-diagnosis是ios平台下的网络诊断SDK,提供的功能有:

  • ping
  • tcp ping
  • traceroute
  • icmp traceroute
  • nslookup
  • port scan

项目地址: github

后续更多关于网络诊断的功能会不断开发完善,欢迎提交issue

另,欢迎fork和star !

掌握iOS网络诊断:实现简单ping功能 命令行接口(Command-Line Interface,CLI)是一种用户界面,允许用户通过文本命令来与计算机系统交互。与图形用户界面(Graphical User Interface,GUI)相比,CLI提供了一种更直接、更高效的方式来执行复杂的任务,尤其是在需要批量处理或自动化操作时。CLI的关键特点在于它的强大灵活性和适应性。用户可以通过脚本实现命令的自动化执行,这对于重复性任务尤其有用。此外,CLI通常比GUI占用更少的系统资源,使其在资源受限的环境下成为更优选择。 阅读详情

相关推荐

IOSpingIp地址

检测 ping Ip地址 是否畅通

iOS网络诊断功能 ping traceroute

有时需要排查移动客户端网络状况的情况,可能由于某些地区网络运营商的问题,导致客户端某些功能不正常,需要按情况ping某域名、traceroute某域名,那么在App内如何更好的实现呢?

月若无涯的专栏 1万+

iOS下实现ping功能

iOS下实现ping功能的一个小小demo,希望对大家有帮助

ios ping网络延迟测速(附带效果图)

效果如图: 用法: var sev = STDPingServices.init(address: nowProxy.host) sev!.callbackHandler = { (item, arr) in if (item?.status == STDPingStatus.didStart) { //...

a787188834的专栏 3294

swift-iOSping(ICMP)网络测试demo

iOS ping(ICMP)网络测试demo,用于在iOS中比较多个地址的丢包率、延迟

怎样在IOS中使用ping代码

这个例子,教会你怎样在ios中使用ping 地址,用来测试网络通不通。

计算机网络基础ios指令,在 iOS 平台实现Ping 和 traceroute

ping 命令Ping是为了测试另一台主机是否可达,现在已经成为一种常用的网络状态检查工具。常见的ping命令:/**** 往目的追击发送固定包数 ****/ping -c 3 www.baidu.com // ping百度发送3个包/**** 设置两次发包之间的等待时间 ****/ping -i 5 www.baidu.com // 两包之间的时间间隔为5sping -i 0.1 www...

weixin_30512965的博客 2341

ios学习笔记---simpleping

ios学习笔记---simpleping 适合初学者练习使用。只是一个小的demo

iOS平台网络诊断SDK常见问题解决方案

iOS平台网络诊断SDK常见问题解决方案 1. 项目基础介绍和主要编程语言 该项目是iOS平台的一个网络诊断SDK,它支持IP和域名的ping测试、UDP和ICMP协议的traceroute、TCP ping、端口扫描、nslookup以及局域网活跃IP扫描等功能。该SDK可以帮助开发者轻松地在iPhone上进行网络诊断操作。主要编程语言为Objective-C和Swift。 2. 新手使用注意事...

gitblog_00150的博客 1093

具身智能ACT模型在lerobot机械臂上的实践与优化

本文详细介绍了如何在低成本lerobot机械臂上实践与优化具身智能ACT模型。从环境搭建、数据采集到模型原理与代码实战,提供了完整的入门指南。重点分享了通过数据增强、混合开源数据集及模型微调等策略,有效提升模型在抓取放置任务中的泛化能力与鲁棒性,为机器人学习爱好者提供了宝贵的实战经验。

weixin_29081703的博客 169

Ubuntu升级遇到grub-efi-amd64-signed报错?3步搞定这个烦人的EFI目录问题

本文详细解析了Ubuntu系统升级时遇到的“grub-efi-amd64-signed”报错及“cannot find EFI directory”问题。通过剖析UEFI启动机制与EFI系统分区原理,提供了从诊断到修复的三步解决方案,帮助用户快速解决因EFI目录未挂载导致的升级中断,确保系统引导正常。

assembly8low的博客 585

iOS网络诊断终极指南:LDNetDiagnoService_IOS快速上手教程

想要快速排查iOS应用中的网络问题吗?LDNetDiagnoService_IOS是一款专为iOS平台设计的网络诊断工具,利用ping和traceroute原理对指定域名进行全面的网络诊断,帮助开发者收集详细的诊断日志。🚀 ## 什么是LDNetDiagnoService_IOS? LDNetDiagnoService_IOS是一个基于Objective-C开发的iOS网络诊断服务库,能够对

gitblog_01102的博客 1009

HDLbits练习11 - Counter 1-12 ( Exam/ece241 2014 q7a )

(如这题用于当复位信号为高或者计数器递增至12时,该信号置1使计数器的输入信号 ’ d ’ 变为 ’ 4’b0001 ’ ,再加载到 ’ Q ’ 中。当 ’ load ’ 信号为高时,在时钟的上升沿,计数器会将 ’ d ’ 输入的值加载到 ’ Q ’ (计数器的输出)中,而不是递增当前值。用途:在时钟上升沿触发的情况下,如果 ’ enable ’ 信号为高,计数器的值会递增,如果 ’ load ’ 信号为高,计数器将加载 ’ d ’ 信号的值。作用: ’ Q ’ 是计数器的当前值,也是模块的主要输出。

weixin_62830176的博客 473

linux 命令:ping、fping、gping、hping3、nping、tracert、traceroute、ip 和 ifconfig

linux 命令:ping、fping、gping、hping3、nping、tracert、traceroute

freeking101的博客 9万+

LM Studio中文版零基础入门:从安装到模型下载的保姆级教程(附国内镜像源配置)

本文提供LM Studio中文版的零基础入门教程,涵盖从软件安装、中文界面切换到国内镜像源配置的全流程。特别针对模型下载速度慢的问题,详细介绍了如何通过修改配置文件使用国内镜像站,并推荐适合新手的入门模型及硬件配置建议,帮助用户快速上手本地大模型运行。

pz890123456的博客 2601

【GD32F407】i2c主机发送,从机中断接收

前言 现在手里负责的一个项目需要用i2c和主芯片进行通信主动发送,中断接收,这就需要支持i2c主机模式和从机模式,先查看原理图 这里我们用到了两条i2c总线进行数据的交替传输,避免在使用一条总线是发送数据和接收数据冲突 初始化i2c控制器 s32_k i2cDevInit(u8 byBusId, TI2cBus *pTI2cBus) { //PCLK = 36000000 BOOL retFlg = FALSE; int I2xSCL = pTI2cBus->byFastMode ?

Enosji的博客 6246

hyperglass支持的网络设备平台全解析:从Arista到VyOS的完整指南

hyperglass是一款现代化的网络Looking Glass工具,旨在让网络运营商能够轻松地为客户、对等方或公众提供查看网络元素和运行测试的能力。作为一个开源项目,hyperglass通过支持广泛的网络设备平台,帮助网络工程师简化网络监控和故障排除工作。本文将全面解析hyperglass支持的13个主要网络设备平台,从企业级的Arista EOS到开源的VyOS,为您提供完整的平台支持指南和配

gitblog_01150的博客 875

本地玩转AI还得靠这个,SillyTavern(酒馆)到底有多强?

SillyTavern是一款本地运行的LLM交互前端,支持文本生成、图像生成、语音合成等功能。它最初是TavernAI的分支,现已独立开发,社区活跃,功能更新频繁。SillyTavern通过前端UI和插件系统连接各种大模型后端,如OpenAI、KoboldAI等,用户可以在本地创建“虚拟酒馆”与各种角色对话。其功能亮点包括角色卡、角色记忆、世界设定、多人聊天室、自定义UI和行为脚本、插件扩展支持等。SillyTavern适合AI创作用户、AI工程师、LLM爱好者和AIGC创作者。它有两个维护分支:relea

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 8042

终极React Native网络诊断指南:从ping到高级网络分析的完整工具包

React Native作为构建跨平台移动应用的强大框架,其网络功能的稳定性直接影响用户体验。本文将系统介绍如何在React Native应用中集成和使用网络诊断工具,包括ping测试、traceroute追踪以及高级网络监控技巧,帮助开发者快速定位和解决网络问题。 ## 📱 React Native网络诊断基础 React Native提供了基础的网络API,但要实现专业的网络诊断功能,需

gitblog_00735的博客 949

【Ubuntu】RK3576 Linux 6.10 Ubuntu 22.04 系统中 HUSB311 Type-C 转 DP 显示输出与 Device/OTG 模式切换配置详解

本文详细介绍了在Rockchip RK3576开发板(Linux Kernel 6.10+Ubuntu 22.04)上配置HUSB311 Type-C控制器的设备树实现方案。主要内容包括:1)硬件连接与模块组成;2)设备树完整配置,涵盖Type-C供电、USB OTG/Host模式、DP显示输出等关键功能;3)软件配置步骤与常见问题排查方法。该方案实现了Type-C接口的DisplayPort AltMode显示输出、USB Device/Host模式自动切换等功能,为嵌入式系统Type-C接口开发提供参考

qq_34478161的博客 808

BUCK-BOOST升降压电路Multisim电路仿真分析

本文分析了三极管型BUCK-BOOST升降压开关电源的工作原理。该电路结合了BUCK降压和BOOST升压拓扑,通过控制三极管Q1的高频通断,使电感L1周期性储能和释能,实现输出电压可高于或低于输入电压且极性相反。详细阐述了Q1导通和关断阶段的工作过程,推导了输出电压与占空比的关系式Vo=-D/(1-D)*Vi,并分析了不同占空比下的工作模式(降压、升压)。通过Multisim仿真验证了理论分析,当D=25%时输出降压至1.6V,D=60%时输出升压至7.5V。电路具有升降压灵活、极性反转、效率高等特点,适用

XU157303764的博客 1436

推荐一款强大的iOS网络诊断工具——Network Diagnosis for iOS

推荐一款强大的iOS网络诊断工具——Network Diagnosis for iOS iOS-netdiagNetwork Diagnosis for iOS项目地址:https://gitcode.com/gh_mirrors/io/iOS-netdiag 在当今高度数字化的世界中,网络的稳定性和性能对移动应用至关重要。为了满足开发者们对高质量网络连接的需求,我们今天向大家推荐一款由七牛科技...

gitblog_00070的博客 1691

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

推荐文章:打造高效网络诊断利器 —— iOS网络诊断SDK

推荐文章:打造高效网络诊断利器 —— iOS网络诊断SDK 在当今这个高度数字化的时代,确保移动应用程序的网络连接稳定至关重要。今天,我们为您介绍一款强大而高效的开源工具——iOS网络诊断SDK,专为解决iOS应用中的网络疑难杂症量身定制。这款神器让您能够在iOS平台上轻而易举地执行ping、traceroute、获取移动公共网络信息、端口扫描等关键网络诊断操作。 项目介绍 iOS网络诊断SDK是...

gitblog_00570的博客 523

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

LDNetDiagnoService_IOS完全指南:iOS网络诊断神器如何精准定位API域名问题

LDNetDiagnoService_IOS是一款专为iOS平台打造的网络诊断工具,它利用ping和traceroute的原理,对指定域名(通常为后台API的提供域名)进行全面网络诊断,并高效收集诊断日志,帮助开发者和用户快速定位网络问题。 ## 一、为什么选择LDNetDiagnoService_IOS进行网络诊断? 在iOS应用开发和使用过程中,网络问题常常是影响用户体验的关键因素。尤其是

gitblog_00090的博客 373

如何通过LDNetDiagnoService_IOS监控网络日志?手把手教你配置TextView实时输出

LDNetDiagnoService_IOS是一款专为iOS平台设计的网络诊断工具,它利用ping和traceroute原理对指定域名进行网络诊断,并收集详细的诊断日志。本文将详细介绍如何配置TextView实现网络日志的实时输出,帮助开发者快速掌握网络状态监控技巧。 ## 📋 准备工作:了解项目结构 在开始配置前,我们先了解一下项目的核心文件结构: - **核心功能模块**:[LDNet

gitblog_00723的博客 407
上一篇: 创建一个 Framework 类型的静态库
mediaios
博客等级 码龄12年 12粉丝 65原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值