DIY TCP/IP IP模块和ICMP模块的实现2

XIAO W5500以太网模块:硬件TCP/IP协议栈赋能嵌入式稳定联网 在嵌入式系统开发中,为微控制器(MCU)实现稳定可靠的网络连接是物联网、工业控制等场景的核心需求。传统软件TCP/IP协议栈会占用大量MCU的CPU和内存资源,而硬件协议栈芯片则通过集成完整的网络协议处理单元,将网络协议解析、数据包封装等复杂任务从主控MCU卸载,显著降低了系统负载与开发门槛。其技术价值在于为资源受限的单片机提供了即插即用的有线以太网解决方案,尤其适用于对网络实时性和稳定性要求高的应用。W5500作为一款经典的全硬件TCP/IP嵌入式以太网控制器,内部集成了8个独立的硬件Socket和零拷贝 阅读详情

上一篇:DIY TCP/IP IP模块和ICMP模块的实现1
本节在8.2节的基础上扩展icmp_recv函数,检验接收到的ICMP数据帧的校验和,解析ICMP数据帧头部的type字段,根据ICMP数据帧的类型做相应处理。

  int icmp_recv(unsigned char *pkt, unsigned int sz)
  {
      int ret = 0;
      iphdr_t *ippkt = NULL;
      icmphdr_t *icmppkt = NULL;
      unsigned short icmppkt_len = 0;
      unsigned char icmp_type = 0;
      unsigned char *payload = NULL;
  
      if (pkt == NULL || sz == 0) {
          ret = -1;
          goto out;
      }
  
      ippkt = (iphdr_t *)pkt;
      icmppkt_len = NTOHS(ippkt->total_len) - sizeof(iphdr_t);
      icmppkt = (icmphdr_t *)strip_header(ippkt, sizeof(iphdr_t));
      if (cksum(0, icmppkt, icmppkt_len, BENDIAN)) {
          log_printf(ERROR, "Invalid ICMP checksum\n");
          ret = -1;
          goto out;
      }
      icmp_type = icmppkt->type;
      log_printf(INFO, "Echo (ping) %s, id: %u, seq: %u/%u, ttl=%u\n",
          icmp_type == ICMP_TYPE_ECHO ? "request" : "reply",
          NTOHS(icmppkt->id), NTOHS(icmppkt->seq), icmppkt->seq,
          ippkt->ttl);
      dump_buf(icmppkt, icmppkt_len);
      switch(icmp_type) {
          case ICMP_TYPE_ECHO:
              ret = process_icmp_echo(ippkt, icmppkt);
              break;
          case ICMP_TYPE_ECHO_REPLY:
              ret = process_icmp_echo_reply();
              break;
          default:
              log_printf(WARNING,
                  "Unhandled ICMP PKT, type: %u\n", icmp_type);
              ret = -1;
              goto out;
      }
  out:
      return ret;
  }


Line 1-13: icmp_recv函数的参数pkt指向IP数据帧的首字节地址,sz是IP数据帧的长度,包括IP头部和IP Payload。pkt的类型是void *,没有定义成iphdr_t *类型,因为icmp_recv函数是ICMP模块暴露给其他模块使用的函数接口,icmp_recv函数声明在icmp.h头文件中,如果定义icmp_recv的入参pkt为iphdr_t *类型,就需要在icmp.h头文件中引入ip.h头文件,造成ICMP模块和IP模块头文件的循环引用。读者还会在其他模块的实现中看到类似的void *类型的函数入参的定义,都是为了避免头文件的循环引用和增加模块之间的独立性。
Line 14-17: 判断入参pkt不为空且sz不为0时继续执行,将pkt强制转换为iphdr_t *类型,根据IP首部的total_len字段计算ICMP数据帧的长度,strip_header将IP数据帧的头部剥去后赋值给icmppkt,strip_header之前已经介绍过,将ippkt指针转换为unsigned char *类型,再加上sizeof(iphdr_t)。
Line 18-22: 检验ICMP数据帧的校验和,8.1节中介绍的ICMP的头部数据和ICMP的payload数据都要参与计算校验和,icmppkt指向的ICMP数据帧的头部中包含发送方的校验和数据,所以此处检验校验和的结果应当为0,否则认为接收到的ICMP数据帧不合法。
Line 23-44: 校验和检验通过后,打印输出接收的到ICMP数据帧的头部信息,dump_buf做为debug使用,输出Echo (Ping) Request数据帧的内容。根据ICMP头部中的type判断,接收到的ICMP数据帧是Echo Ping Rquest或者是Echo Ping Reply,再交给process_icmp_echo和process_icmp_echo_reply函数处理。
8.4 ICMP数据帧的发送
本节在8.3节的基础上扩展process_icmp_echo函数,构造ICMP Echo (Ping) Reply数据帧,复制ICMP Echo Ping Request数据帧的payload数据,计算ICMP数据帧的校验和,将构造好的ICMP Echo Ping Reply数据帧交给IP模块发送。在介绍代码实现之前,先来通过wireshark抓取PING的数据帧交互过程,查看如何构造ICMP Echo (Ping) Reply数据帧。
DIY TCP/IP Ping Router Sample
上图是本人所在局域网中的一台windows主机PING路由器的交互过程,192.168.0.105发出Echo (ping) Request,路由器192.168.0.1回复Echo (ping) Reply。
Echo (ping) Requset数据帧
DIY TCP/IP Ping Request
Echo (Ping) Request数据帧头部结构已经在8.1节详细介绍过,data部分含有32个字节的数据,从wireshark的raw byte数据显示可以看出,32个字节的data是ascii码小写的a到w,再重复小写的a到i。
Echo (ping) Reply数据帧
DIY TCP/IP Ping Reply
Echo (ping) Reply的identifier,sequence number与Echo (ping) Request相等,在8.1节已经介绍过,RFC792 ICMP协议中有说明,ICMP头部code为0时,Echo ping Request和Echo Ping Reply的identifier,sequence number字段分别相等。表示Echo Ping Reply回复对应的Echo ping request数据帧。再来看数据部分,32个字节的数据也是相等的,与ICMP Echo数据帧的名字相呼应,接收到Echo (Ping) Request数据帧时,将数据原封不动的Echo回去。Echo (Ping) Reply除了type和校验和部分与Echo (Ping) Request不相等之外,其余部分均相等。弄清楚Echo (Ping) Reply数据帧的回复规则后,再来看process_icmp_echo的代码实现。

 static int process_icmp_echo(iphdr_t *ippkt, icmphdr_t *echo_req)
 {
  int ret = 0;
  unsigned short data_len = 0;
  unsigned char *echo_req_data = NULL;
  icmphdr_t *echo_reply = NULL;
  pdbuf_t *pdbuf = NULL;
 
  if (ippkt == NULL || echo_req == NULL) {
      ret = -1;
      goto out;
  }
 
  echo_req_data = strip_header(echo_req, sizeof(icmphdr_t));
  data_len = NTOHS(ippkt->total_len) -
          sizeof(iphdr_t) - sizeof(icmphdr_t);
  pdbuf = pdbuf_alloc(data_len, !IGNORE_MTU);
  if (pdbuf == NULL) {
      ret = -1;
      goto out;
  }
  /* build icmp reply */
  pdbuf_push(pdbuf, data_len);
  memcpy(pdbuf->payload, echo_req_data, data_len);
  pdbuf_push(pdbuf, sizeof(icmphdr_t));
  echo_reply = (icmphdr_t *)pdbuf->payload;
  echo_reply->type = ICMP_TYPE_ECHO_REPLY;
  echo_reply->code = ICMP_CODE;
  echo_reply->cksum = 0;
  echo_reply->id = echo_req->id;
  echo_reply->seq = HSTON(icmp_seq ++);
  echo_reply->cksum = cksum(0, echo_reply,
              data_len + sizeof(icmphdr_t), BENDIAN);
  echo_reply->cksum = HSTON(echo_reply->cksum);
  dump_buf(echo_reply, data_len + sizeof(icmphdr_t));
 out:
  return ret;
 }
 
 static int process_icmp_echo_reply()
 {
  int ret = 0;
  return ret;
 }

process_icmp_echo函数的入参是ippkt指针和icmppkt指针,分别指向IP数据帧的首字节地址,和ICMP数据帧的首字节地址。之所以需要IP数据帧,是因为ICMP Echo (Ping) Reply数据帧构造完成之后,需要将其交给IP模块的发送函数处理,发送的目标IP地址就是ICMP Request数据帧的IP头部中的源IP地址。
Line 1-16: 判断ippkt和icmppkt指针都不为空时继续执行,虽然icmp_recv到process_ecmp_echo的调用,ippkt和icmppkt指针必然不为空,本人编写C语言习惯先检查指针的合法性,再使用指针。调用strip_header将ICMP数据帧的头部剥去,返回的指针赋值给echo_req_data,echo_req_data指向ICMP Echo (Ping) Request的数据部分的首字节地址。通过IP头部的total_len字段减去IP头部长度和ICMP头部长度,得到Echo (ping) Request数据部分的长度。
Line 17-21: pdbuf_alloc申请长度为data_len的buffer,6.4节已经介绍过pdbuf_alloc申请的内存空间包括data_len,Layer3和Layer4最大的协议头部,以太网头部和pdbuf_t描述符本身占用的全部内存空间。pdbuf_alloc的第二个参数是!IGNORE_MTU,表示最大申请1500字节的内存空间。介绍IP分片的重组时,会再次改写该函数,重组后的IP分片,封装的ICMP数据帧的长度会超过1500字节。
Line 22-26: pdbuf_push调整pdbuf->payload向地址减小的方向移动data_len个字节,首先将Echo Request的数据部分复制到pdbuf->payload指向的内存空间。再将pdbuf->payload向地址减小的方向移动sizeof(icmphdr_t)个字节,用于存放ICMP的头部数据。将pdbuf->payload指针强制转换为icmphdr_t *类型,用于构造ICMP头部数据。
Line 27-38: type为0x0,code为0x0,cksum字段先赋值为0,最后计算校验和的数值。Identifier和sequence number都来自Echo (ping) Request数据帧,已经是大端格式,所以不需要再次转换为大端。计算校验和,参与计算的数据包括Echo (ping) Reply的头部数据和Payload数据。校验和计算完成后再转换为大端格式填入Echo (ping) Reply数据帧的头部cksum字段中。dump_buf做为debug使用,在将Echo (ping) Reply数据帧交给IP模块发送之前,先通过dump_buf查看构造的数据帧是否符合预期。
与8.2的测试方法一致,运行DIY TCP/IP的主机记为A,与主机A在同一个局域网的主机B上Ping主机A,8.3节在完成ICMP数据帧的校验和检查后,dump_buf打印Echo Ping Request数据帧的内容,本节在ICMP数据帧的校验和计算完成后,dump_buf打印回复构造的Echo Ping Reply数据帧的内容。
主机B PING 192.168.0.7,该IP地址是DIY TCP/IP的虚拟IP地址(局域网中不存在),本节只是构造了ICMP Echo Ping Reply,并没有将数据帧交给IP模块发送,所以主机B上PING的结果仍然是失败的。
DIY TCP/IP Ping Result
再来看DIY TCP/IP的运行结果

gannicus@ubuntu:~/guojia/tasks/DIY_USER_SPACE_TCPIP/ch5/2$ sudo ./tcp_ip_stack -i 192.168.0.7
[sudo] password for gannicus: 
Network device init
filter: ether proto 0x0800 or ether proto 0x0806
Network device RX init
Network device TX init
Net device ip address: 192.168.0.7
192.168.0.7 is at 00:0c:29:2e:0a:ed
ARP Table
IP Address      MAC Address
192.168.0.105       8c:a9:82:11:d1:de
Echo (ping) request, id: 1, seq: 16/4096, ttl=64
08 00 4d 4b 00 01 00 10 61 62 63 64 65 66 67 68
69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 61
62 63 64 65 66 67 68 69 
Echo (ping) reply, id: 1, seq: 16/4096, ttl=64
00 00 55 4b 00 01 00 10 61 62 63 64 65 66 67 68
69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 61
62 63 64 65 66 67 68 69 
Echo (ping) request, id: 1, seq: 17/4352, ttl=64
…

从运行结果可以看出,ICMP模块接收到了Echo (PIing) Request,并且校验和检验成功,Echo (ping) request的type为0x08,0x0为code,4d 4b 为大端格式的校验和,00 01是大端格式的identification,00 10也是大端格式的sequence number,从61向后,一直到第40个字节是Echo (ping) Request的数据内容。
再来看本节构造的Echo (Ping) Reply,type为0x00,0x0为code,55 4b是大端格式的校验和,identification和sequence number与Echo (Ping) Request相等,后面的数据部分也相等,运行结果符合预期。
下一篇:DIY TCP/IP IP模块和ICMP模块的实现3

Canoe CAPL TCP通信避坑指南:从OnTcpConnect回调不触发到Socket句柄管理 本文详细解析了Canoe CAPL中TCP通信的常见问题与解决方案,包括OnTcpConnect回调不触发的三大原因、Socket句柄管理的内存泄漏风险、数据发送截断规则等。通过实战案例和代码示例,帮助开发者规避TCP通信中的典型陷阱,提升车载网络测试的稳定性和可靠性。 阅读详情

相关推荐

一个基于ZYNQ、AXI接口的PL端卷积加速器,可由PS端调用(附Github源码)

一个基于ZYNQ,AXI接口的PL端卷积加速器,可由PS端调用开发板型号:Zynq-7000 SoC XC7Z305 FPGA开发平台:Vivado 2019.1;Github源码链接:https://github.com/CY0807/ZYNQ_PL_CONV_ACC。

跳跳骑士的博客 1306

DIY TCP/IP TCP模块的实现2

上一篇:DIY TCP/IP TCP模块的实现1 9.4 TCP连接的初始化 TCP是面向连接的协议,面向连接即有状态的协议。通信双方通过三步握手,达到连接建立的状态,然后基于这种状态交互TCP数据帧。断开连接是通信双方通过四步握手达到断开连接的状态。9.1节提到<源IP地址,源端口,目标IP地址,目标端口>四元组可以标识通信双方建立的TCP连接。所以定义TCP连接的数据结构应包括四元...

Gannicus.Guo的博客 586

NVMe与PCIe的完美结合:高速存储背后的技术解析

本文深入解析了NVMe与PCIe技术如何完美结合,实现高速存储性能的飞跃。从机械硬盘到NVMe SSD的进化历程出发,详细介绍了PCIe总线的高带宽优势与NVMe协议的低延迟设计,以及两者协同工作带来的显著性能提升。通过实测数据对比,展示了NVMe SSD在消费级和企业级应用中的卓越表现,并提供了选购与优化建议。

weixin_29216353的博客 376

DIY TCP/IP TCP模块的实现0

上一篇:DIY TCP/IP IP模块和ICMP模块的实现6 9. TCP模块的实现 本章实现DIY TCP/IP的TCP模块,目标是DIY TCP/IP可以支持局域网内iperf TCP吞吐量测试。围绕该目标将本章内容分为:TCP数据帧结构介绍;TCP伪首部介绍;TCP三步握手的实现,三步握手的实现还包括,TCP连接数据结构的定义,围绕TCP连接数据结构,实现简单的TCP连接状态机;TCP滑动窗...

Gannicus.Guo的博客 612

Ubuntu22.04+Docker一键部署Autoware Universe避坑指南(附鱼香ROS配置)

本文详细介绍了在Ubuntu22.04系统中使用Docker一键部署Autoware Universe的完整流程,包括鱼香ROS工具链配置、Docker环境优化及VSCode开发环境集成。通过实战指南帮助开发者快速搭建自动驾驶开发环境,解决常见部署问题,提升开发效率。

weixin_29254673的博客 414

高通SDX35:SGMII接口PHY RTL8211FSI-CG驱动适配

高通SDX35 RTL8211F SGMII

不秃头的程序猿Gabriel的博客 786

万兆以太网MAC设计(8)ICMP协议详解以及ICMP层模块设计

ICMP (Internet Control Message Protocol) 协议被设计用来向 IP 源端报告差错及其它相关信息, IP 协议本身只设置有 Checksum 机制来保证数据的正确性, 它本身提供不可靠的服务, ICMP 协议可以用来当发送差错时向源端报告相应的问题, 可以一定程度上提高 IP Datagram 交付的可靠性, 其协议的标准文档为 1981 年 9 月发布的 RFC 792, 本文讨论 ICMP 协议的设计,ICMP 不是 IP 协议之上的协议, ICMP 的 PDU 被封

m0_56222647的博客 1460

图像处理入门007:图像处理中的数学基础:线性代数与卷积

一种:把 OpenCV 当黑盒,调用,效果不对就乱调参数;另一种:理解每个像素是怎么被周围邻域"加权平均"的,理解核翻转、边界填充、stride 的含义。前者能干活,后者能解难题。一旦遇到自定义核(比如 ISP 上的锐化)、深度学习反向传播、医学图像重建,你就必须把卷积、相关、矩阵乘法这些基本功捡回来。线性代数三件套:向量点积、矩阵乘法、线性变换;2D 卷积的数学定义:核翻转、滑动窗口、边界填充。并手写一个,验证它与和的结果完全一致(误差 < 1e-9)。f∗gn∑m−∞∞f。

专注:太空算力、AI infra、异构调度、大模型成本工程 386

DIY TCP/IP IP模块和ICMP模块的实现3

上一篇:DIY TCP/IP IP模块和ICMP模块的实现2 8.5 IP数据帧的发送 本节为构造好的ICMP (Ping) Reply添加IP头部,根据目标IP地址查找ARP模块的ARP表,在IP头部前面再添加以太网头部,最终通过DIY TCP/IP的网络设备模块把Echo (Ping) Reply发送到对方主机。本章一直沿用的测试都是在与运行DIY TCP/IP的主机A,处于同一局域网的另外一...

Gannicus.Guo的博客 424

从 AccessControl.authorizationCheck 读懂 ABAP CDS 访问控制:默认策略、取舍边界与一线项目实战

摘要: 本文深入解析ABAP CDS视图中@AccessControl.authorizationCheck注解的核心功能与工程实践。该注解通过DCL角色实现行级数据过滤,提供三类能力:控制访问生效条件、约束语义一致性及管理特权访问。文章详述四种注解取值(#CHECK、#NOT_REQUIRED、#NOT_ALLOWED、#PRIVILEGED_ONLY)的适用场景与默认行为,并结合采购订单案例演示DCL与PFCG授权的落地步骤。同时指出访问控制的边界问题(如JOIN场景可能绕过过滤),并给出视图层级决策矩

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 260

数据处理和分析之数据预处理:数据离散化

在某些情况下,根据业务知识或数据特性,我们可能需要自定义离散化的区间。例如,对于年龄特征,我们可能更关心儿童、青少年、成人和老年人这几个阶段,因此可以自定义这些区间。等宽离散化:将数据范围分成等宽的区间。等频离散化:将数据分成包含相同数量观测值的区间。聚类离散化:使用聚类算法(如K-means)来确定离散化区间。自定义区间离散化:根据领域知识或数据特性手动定义区间。# 自定义区间离散化示例# 假设我们根据业务理解,将年龄分为青年、中年和老年三个阶段。

2401_87715305的博客 934

Linux内核分析 - 网络[十一]:ICMP模块

内核版本:2.6.34   ICMP模块比较简单,要注意的是icmp的速率限制策略,向IP层传输数据ip_append_data()和ip_push_pending_frames()。 在net/ipv4/af_inet.c中的inet_init()注册icmp协议,从这里也可以看出,ICMP模块是绑定在IP模块之上的。inet_add_protocol()会将icmp_protocol加入到

yoyo的专栏 1万+

sam3.1 部署笔记 推理封装

sam3.1 部署笔记

jacke121的专栏 424

DIY TCP/IP IP模块和ICMP模块的实现1

上一篇:DIY TCP/IP IP模块和ICMP模块的实现0 8.2 IP数据帧的接收 本节实现DIY TCP/IP的IP数据帧的接收,6.1节介绍pdbuf模块时已经引入了IP头部结构体的定义,iphdr_t数据结构定义在ip.h头文件中。本节围绕该数据结构的定义,实现IP模块对IP数据帧的解析,IP头部校验和的检验,并根据IP头部的上层协议字段将IP数据帧分发给DIY TCP/IP的对应模块处...

Gannicus.Guo的博客 435

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

DIY TCP/IP IP模块和ICMP模块的实现6

上一篇:DIY TCP/IP IP模块和ICMP模块的实现5 8.8 IP分片的发送 本节在8.7节的基础上修改ICMP模块对ICMP Echo Ping Reuqest的处理,构建ICMP Echo Ping Reply 数据帧,将长度超过MTU_SIZE (1500字节)的ICMP Echo Ping Reply数据帧交给IP模块 ,在IP模块添加IP分片的实现,并发送IP分片。IP分片是重组...

Gannicus.Guo的博客 328

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

DIY TCP/IP IP模块和ICMP模块的实现5

上一篇:DIY TCP/IP IP模块和ICMP模块的实现4 8.7 IP分片的接收 本节实现DIY TCP/IP对IP 分片的接收,需要正确检验每个IP分片首部的校验和,将属于同一个identification的IP分片全部正确接收后,按照分片数据的偏移量,重新组合上层协议数据帧,再将重组后的数据帧交给相应模块处理。本节的验证是通过Large Packet Ping,如果重组后的IP数据帧交给I...

Gannicus.Guo的博客 409

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

DIY TCP/IP IP模块和ICMP模块的实现4

上一篇:DIY TCP/IP IP模块和ICMP模块的实现3 8.6 IP分片 在介绍DIY TCP/IP接收IP分片的代码实现之前,本节先通过wireshark抓包来分析,如何判断一个IP数据帧是一个IP分片,如何判断分片的开始和结束,收到IP分片后如何重组分片。通过wireshark抓取指定长度(超过MTU 1500字节)的PING数据帧过程,便于描述,将该过程称为Large Packet P...

Gannicus.Guo的博客 580

DIY TCP/IP IP模块和ICMP模块的实现0

上一篇:DIY TCP/IP ARP模块3 8. IP模块和ICMP模块的实现 本章介绍DIY TCP/IP的IP模块和ICMP模块的实现,ARP模块的目标是在与本机处于同一局域网的另外一台主机上建立DIY TCP/IP的虚拟IP地址和本机网络接口的硬件地址的映射。本章的目标是同一局域网的另外一台主机上能够PING通DIY TCP/IP的虚拟IP地址。达到这个目标需要实现ICMP Echo数据帧的...

Gannicus.Guo的博客 344

DIY TCP/IP ARP模块0

上一篇:DIY TCP/IP Payload Buffer模块2 7. ARP模块的实现 本章介绍DIY TCP/IP ARP模块的实现,回顾第一章可行性分析中的描述,DIY TCP/IP 上层模块包括ICMP,IP,TCP和UDP协议帧的接收和发送,都依赖于ARP先建立虚拟IP地址和运行DIY TCP/IP 主机的MAC地址的映射。便于验证,DIY TCP/IP各个模块都是先实现接收,ARP模块...

Gannicus.Guo的博客 362

DIY TCP/IP Payload Buffer模块0

pdbuf模块的实现 pdbuf是payload buffer的简称,该模块为DIY TCP/IP提供buffer管理功能,与Linux Kernel的struct sk_buff类似。pdbuf模块提供buffer的动态分配和释放,为有效载荷分配内存时预留协议头部所需内存空间,同时保证有效载荷加上协议头部(不包括14个字节的以太网头部)的大小不超过以太网的最大协议传输单元1500字节。pdbu...

Gannicus.Guo的博客 628

Gannicus Guo的DIY TCP/IP之旅

Gannicus Guo的DIY TCP/IP之旅,描述本人自己动手写的一个简化的TCP/IP协议。经测试该协议可以运行在Ubuntu 16.10 x86_64 操作系统用户空间。便于描述,将该TCP/IP协议称为DIY TCP/IP 。专栏内容包括DIY TCP/IP实现的可行性分析,依赖的编程接口,ARP数据帧的收发,ICMP Echo (PING)数据帧的收发,简单的基于ARP表的IP路由,...

Gannicus.Guo的博客 987

Gannicus Guo的DIY TCP/IP 连载目录

Gannicus Guo的DIY TCP/IP 连载目录 该专栏描述本人自己动手写的一个简化的TCP/IP协议。经测试该协议可以运行在Ubuntu 16.10 x86_64 操作系统用户空间。便于描述,将该TCP/IP协议称为DIY TCP/IP 。专栏内容包括DIY TCP/IP实现的可行性分析,依赖的编程接口,ARP数据帧的收发,ICMP Echo (PING)数据帧的收发,简单的基于ARP表...

Gannicus.Guo的博客 330

DIY TCP/IP 网络设备模块6

上一篇:DIY TCP/IP 网络设备模块5 介绍DIY TCP/IP网络设备模块之上的其他模块的实现之前,本节先来完成log的分级打印。5.3.4节运行结果的打印输出已经相对复杂,目前DIY TCP/IP的log均是通过printf打印到标准输出,上层模块实现之后会有更多的log输出。避免过多的打印信息,实现log的分级打印。本节引入两个新的文件debug.c和debug.h,做为DIY TCP...

Gannicus.Guo的博客 300

DIY TCP/IP Payload Buffer模块1

上一篇:DIY TCP/IP Payload Buffer模块1 6.2 pdbuf数据结构 本节新增pdbuf.h头文件,定义pdbuf数据结构和pdbuf模块的接口函数。pdbuf模块所有操作函数的实现,以及DIY TCP/IP的ARP,IP,ICMP,TCP,UDP等模块的组帧操作,都是基于本节定义的pdbuf_t数据结构。 #ifndef _PDBUF_H_ #define _PDBU...

Gannicus.Guo的博客 534

内网渗透系列:内网隧道之ICMP隧道

最近开始研究隧道相关,如前做了个整理——内网渗透系列:内网穿透(隧道)学习,本篇专门来学习ICMP隧道

闵行小鱼塘 4026

TCP/IP协议栈概述及各层包头分析

一、摘要   对之前几篇博文涉及到的网络通信协议进行分析,概述出TCP/IP的协议栈模型,最后根据实例对各层包头进行分析。   二、标准TCP/IP协议栈模型   标准TCP/IP协议是用于计算机通信的一组协议,通常被称为TCP/IP协议栈,以它为基础组建的互联网是目前国际上规模最大的计算机网络。正因为互联网的广泛应用,使得TCP/IP成为了事实上的网络标准。 1、O

Season@HangZhou 专栏 1186
上一篇: DIY TCP/IP IP模块和ICMP模块的实现1
下一篇: DIY TCP/IP IP模块和ICMP模块的实现3
gannicus.guo
博客等级 码龄19年 25粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值