zcu102_12_Standalone以太网数据的UDP传输

2023-05-16

本文在PS的Standalone程序中使用lwip库通过UDP协议实现网络数据传输。

包含UDP Server和UDP Client两种形式

本文主要参考lwip的SDK内部说明和工程模板,xapp1026, xapp1306, SDK以及两篇博客:

https://www.cnblogs.com/54zorb/p/9609021.html

https://www.cnblogs.com/54zorb/p/9609111.html
本文配套源码已上传至
https://download.csdn.net/download/botao_li/10997950

Block Design

建立zcu102的Vivado工程,新建Block Design,并且添加zynq模块

运行Run Block Automation,双击打开zynq模块配置查看GEM接口配置
在这里插入图片描述
GEM3的配置与ug1182一致
在这里插入图片描述
在这里插入图片描述
保留UART和GEM3,关闭其它外设接口以及PS-PL接口
在这里插入图片描述
确保TTC 0已使能
在这里插入图片描述
保存后依次运行Generate Output Products和Create HDL Wrapper

在Flow Navigator中选择Generate Bitstream,完成后先Export Hardware,再Launch SDK

PS程序

在SDK中可以使用lwip模板新建包含lwip库示例代码的模板工程

注意zuc102开发板生成的模板工程会在IicPhyReset()函数编译出错,将此函数注释掉,用开发板上下电代替复位(试验中发现即使不上下电能正常工作)
在这里插入图片描述
在这里插入图片描述
建完首个工程后,其它工程建立时可以选择使用已有BSP工程
在这里插入图片描述
本文新建空工程用于试验

建立工程后SDK进行自动编译,完成之后在BSP工程配置lwip库(否则可能出现不可理解的异常错误)

在BSP工程上,右键菜单选择Board Support Package Settings
在这里插入图片描述
进入Settings窗口,在Overview界面选中lwip库(如果建立的是lwip模板工程,则BSP工程已自动添加lwip库)
在这里插入图片描述

配置完成后点击OK

打开BSP工程中的system.mss文件,可以在最下方发现lwip库,选择Documentation可以打开说明文档
在这里插入图片描述

在工作工程的src文件夹上右键菜单新建C Source File
在这里插入图片描述
在这里插入图片描述

进入文件main.c,双击打开main.c文件,写入以下代码

#include <stdio.h>
#include "xparameters.h"
#include "netif/xadapter.h"
#include "lwipopts.h"
#include "xil_printf.h"
#include "sleep.h"
#include "lwip/priv/tcp_priv.h"
#include "lwip/init.h"
#include "lwip/inet.h"
#include "lwip/ip_addr.h"
#include "lwip/udp.h"
#include "xil_cache.h"

#include "xscugic.h"
#include "xttcps.h"

//定时器相关定义***************************************************
static XTtcPs TimerInstance;
static u16 Interval;
static u8 Prescaler;

#define INTC_DEVICE_ID		XPAR_SCUGIC_SINGLE_DEVICE_ID
#define TIMER_DEVICE_ID		XPAR_XTTCPS_0_DEVICE_ID
#define TIMER_IRPT_INTR		XPAR_XTTCPS_0_INTR
#define INTC_BASE_ADDR		XPAR_SCUGIC_0_CPU_BASEADDR
#define INTC_DIST_BASE_ADDR	XPAR_SCUGIC_0_DIST_BASEADDR
#define PLATFORM_TIMER_INTR_RATE_HZ (4)

//中断响应函数与main函数都访问的变量,加volatile前缀,不进入cache
volatile int TcpFastTmrFlag = 0;
volatile int TcpSlowTmrFlag = 0;

void platform_clear_interrupt( XTtcPs * TimerInstance )
{
	u32 StatusEvent;

	StatusEvent = XTtcPs_GetInterruptStatus(TimerInstance);
	XTtcPs_ClearInterruptStatus(TimerInstance, StatusEvent);
}

void timer_callback(XTtcPs * TimerInstance)
{
	/* we need to call tcp_fasttmr & tcp_slowtmr at intervals specified
	 * by lwIP. It is not important that the timing is absoluetly accurate.
	 */
	static int odd = 1;
    TcpFastTmrFlag = 1;
	odd = !odd;
	if (odd)
	{
		TcpSlowTmrFlag = 1;
	}
	platform_clear_interrupt(TimerInstance);
}

void platform_setup_timer(void)
{
	int Status;
	XTtcPs * Timer = &TimerInstance;
	XTtcPs_Config *Config;

	//设置Timer之前保证Timer已停止
	XTtcPs_Stop(Timer);

	Config = XTtcPs_LookupConfig(TIMER_DEVICE_ID);

	Status = XTtcPs_CfgInitialize(Timer, Config, Config->BaseAddress);
	if (Status != XST_SUCCESS) {
		xil_printf("In %s: Timer Cfg initialization failed...\r\n",
				__func__);
				return;
	}
	XTtcPs_SetOptions(Timer, XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE);
	XTtcPs_CalcIntervalFromFreq(Timer, PLATFORM_TIMER_INTR_RATE_HZ, &Interval, &Prescaler);
	XTtcPs_SetInterval(Timer, Interval);
	XTtcPs_SetPrescaler(Timer, Prescaler);
}

void platform_setup_interrupts(void)
{
	Xil_ExceptionInit();

	XScuGic_DeviceInitialize(INTC_DEVICE_ID);

	/*
	 * Connect the interrupt controller interrupt handler to the hardware
	 * interrupt handling logic in the processor.
	 */
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
			(Xil_ExceptionHandler)XScuGic_DeviceInterruptHandler,
			(void *)INTC_DEVICE_ID);
	/*
	 * Connect the device driver handler that will be called when an
	 * interrupt for the device occurs, the handler defined above performs
	 * the specific interrupt processing for the device.
	 */
	XScuGic_RegisterHandler(INTC_BASE_ADDR, TIMER_IRPT_INTR,
					(Xil_ExceptionHandler)timer_callback,
					(void *)&TimerInstance);
	/*
	 * Enable the interrupt for scu timer.
	 */
	XScuGic_EnableIntr(INTC_DIST_BASE_ADDR, TIMER_IRPT_INTR);

	return;
}

//udp操作函数*************************************************
static struct pbuf *packet;
static unsigned char send_byte = 0x31;
static err_t err;
static ip_addr_t ip_remote;
//发送数据缓冲
#define SEND_BUFSIZE 16
static char send_buf[SEND_BUFSIZE];

static struct udp_pcb *server_pcb;//UDP Server对象
static struct udp_pcb *client_pcb;//UDP Client对象
#define UDP_SERVER_PORT 5001

void udp_server_recv(void *arg, struct udp_pcb *tpcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
	xil_printf("server recv\r\n");

	//回传数据
	udp_sendto(tpcb, p, addr, port);

	//发送数据
	err = udp_sendto(tpcb, packet, &ip_remote, 8000);
	if (err != ERR_OK)
	{
		xil_printf("fail udp_sendto\r\n");
	}
	send_byte++;
	if (send_byte == 0x39) send_byte = 0x31;
	memset(packet->payload, send_byte, SEND_BUFSIZE);

	//释放pbuf
	pbuf_free(p);
	return;
}

void udp_client_recv(void *arg, struct udp_pcb *tpcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
	xil_printf("client recv from sender port %d\r\n", port);

	//发送接收数据的消息
	sprintf(send_buf, "recv port:%04d", port);
	memcpy(packet->payload, send_buf, SEND_BUFSIZE);

	err = udp_sendto(tpcb, packet, &ip_remote, 8000);//发送给指定IP的指定端口
	err = udp_send(tpcb, packet);//发送给tpcb的remote_ip的remote_port

	if (err != ERR_OK)
	{
		xil_printf("fail udp_send\r\n");
	}

	//释放pbuf
	pbuf_free(p);
	return;
}

void udp_server_init(void)
{
	err_t err;

	//建立PCB对象
	server_pcb = udp_new();
	if (!server_pcb)
	{
		xil_printf("fail udp server udp_new\r\n");
		return;
	}

	//绑定本地IP和端口,UDP Server接收本地收到的发往该端口的数据包
	err = udp_bind(server_pcb, IP_ADDR_ANY, UDP_SERVER_PORT);
	if (err != ERR_OK)
	{
		xil_printf("fail udp server udp_bind\r\n");

		//清除udp对象
		udp_remove(server_pcb);
		return;
	}

	//绑定接收数据回调函数
	udp_recv(server_pcb, udp_server_recv, NULL);

	xil_printf("udp server ready\r\n");
}

void udp_client_init(void)
{
	err_t err;

	//建立PCB对象
	client_pcb = udp_new();
	if (!client_pcb)
	{
		xil_printf("fail udp client udp_new\r\n");
		return;
	}

	//连接之前local_port和remote_port都为0
	xil_printf("udp client local_port b4 connect: %d\r\n", client_pcb->local_port);
	xil_printf("udp client remote_port b4 connect: %d\r\n", client_pcb->remote_port);

	//连接远端的UDP Server,目标端口33
	//连接后可以使用udp_send函数,不用指定远端IP和端口
	err = udp_connect(client_pcb, &ip_remote, 33);
	if (err != ERR_OK)
	{
		xil_printf("fail udp client udp_connect\r\n");

		//清除udp对象
		udp_remove(client_pcb);
		return;
	}

	xil_printf("udp client local_port: %d\r\n", client_pcb->local_port);
	xil_printf("udp client remote_port: %d\r\n", client_pcb->remote_port);

	//绑定接收数据回调函数
	udp_recv(client_pcb, udp_client_recv, NULL);

	xil_printf("udp client ready\r\n");
}

int main(void)
{
	//定时器初始化*********************************************
	platform_setup_timer();
	platform_setup_interrupts();

	//建立网络接口*********************************************
	//定义网络接口对象指针
	struct netif server_netif;//网络接口对象
	struct netif* netif;
	netif = &server_netif;

	//定义mac地址
	unsigned char mac_ethernet_address[] = {0x00, 0x0a, 0x35, 0x00, 0x01, 0x02};

	//lwip库初始化
	lwip_init();

	//定义本地IP
	ip_addr_t ipaddr, netmask, gw;
	IP4_ADDR(&ipaddr,  10, 20, 30, 10);
	IP4_ADDR(&netmask, 255, 255, 255,  0);
	IP4_ADDR(&gw,      10, 20, 30,  1);

	//添加网络接口至接口列表,并且设置为默认
	if (!xemac_add(netif, &ipaddr, &netmask, &gw, mac_ethernet_address, XPAR_XEMACPS_0_BASEADDR))
	{
		xil_printf("Error adding N/W interface\r\n");
		return -1;
	}
	netif_set_default(netif);

	//将当前网络接口提至最前(不理解意义)
	netif_set_up(netif);

	//使能并且启动定时器中断
	Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
	XScuGic_EnableIntr(INTC_DIST_BASE_ADDR, TIMER_IRPT_INTR);
	XTtcPs_EnableInterrupts(&TimerInstance, XTTCPS_IXR_INTERVAL_MASK);
	XTtcPs_Start(&TimerInstance);

	//定义发送数据接收方的IP
	IP4_ADDR(&ip_remote, 10, 20, 30, 22);

	//建立发送数据pbuf
	//layer参数选择为PBUF_RAW表示没有除payload以外的其它路由数据参与发送
	//用pbuf_free(packet)释放
	packet = pbuf_alloc(PBUF_RAW, SEND_BUFSIZE, PBUF_POOL);
	if (packet == NULL)
	{
		xil_printf("fail pbuf_alloc");
		return -1;
	}
	//将待发送数据写入pbuf的payload中
	memset(packet->payload, send_byte, SEND_BUFSIZE);

	//启动udp
	udp_server_init();
	udp_client_init();

	//程序主循环
	while (1)
	{
		//无论是UDP还是TCP都必须包含tcp_fasttmr()和tcp_slowtmr()
		if (TcpFastTmrFlag)
		{
			tcp_fasttmr();
			TcpFastTmrFlag = 0;
		}
		if (TcpSlowTmrFlag)
		{
			tcp_slowtmr();
			TcpSlowTmrFlag = 0;
		}

		//网络接口处理接收数据
		xemacif_input(netif);
	}

	return 0;
}

前述代码的网络功能说明:

  • PS网络IP为10.20.30.10
  • UDP Server绑定端口为5001
  • UDP Server收到数据后会将数据原样返回发送方,并且向10.20.30.22的IP地址的8000端口发送递增数据
  • UDP Client连接的目标IP为10.20.30.22,目标端口为33
  • UDP Client接收到数据后,向10.20.30.22的IP地址的8000端口和目标Server发送文字

试验

将zcu102板卡的网口通过网线与测试主机连接

打开windows设置界面,选择网络和Internet
在这里插入图片描述

在状态页选择更改适配器选项
在这里插入图片描述
在以太网连接图标上右键菜单选择属性
在这里插入图片描述

选中Internet协议版本4(TCP/IPv4)选项后,点击属性打开IPv4配置,按下图设置后,点击确定保存设置内容
在这里插入图片描述

将zcu102的启动模式设置为JTAG,上电启动

在windows的适配器选项窗口可见网络连接已建立

打开网络调试助手,设置为UDP协议,选择前述设置的IP地址,根据SDK代码选择主机端口33后点击打开
在这里插入图片描述

打开另一个网络调试助手进程,按如下设置
在这里插入图片描述

打开串口调试助手,按下图配置并且连接COM4
在这里插入图片描述

在SDK中的工作工程右键菜单选择Run As > Launch on Hardware(System Debugger)
在这里插入图片描述

在串口助手中发现UDP Client连接后分配的端口为49153
在这里插入图片描述

在试验中可以发现PS端UDP Client不响应从PC端的8000端口发送数据,因为PS端UDP Client已与PC端的33端口完成连接,只响应来自PC端33接口发来的UDP数据

完整试验内容如下
在这里插入图片描述

注意

UDP Client的Connect没有实际的数据交换,仅仅是绑定远端IP和端口。因此,即使远端的UDP Server没有启动,Connect一样正确返回。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

zcu102_12_Standalone以太网数据的UDP传输 的相关文章

  • 在 Pixel 2 和 Pixel 2 XL 上接收 UDP 广播数据包

    我正在开发一个从 Wi Fi 摄像头接收 UDP 广播数据包的应用程序 在我发现 Google Pixel 2 Pixel 2 XL 接收 UDP 广播包有问题之前一直都很好 为了找出原因 我做了2个测试应用程序 一个是UPD广播发送器 h
  • python udp客户端超时机制

    如果服务器套接字中生成的兰特数小于4 我的客户端套接字将暂停接收数据 我需要设置超时机制以允许客户端套接字检测到 超时 然后继续发送消息 在我运行服务器套接字然后运行客户端套接字后 出现以下错误消息 Traceback most recen
  • 如何在 Docker 上发布 UDP 端口?

    如何将 UDP 端口从 Docker 容器转发到主机 使用 p 标志并添加 udp端口号的后缀 p 53160 53160 udp 完整命令 sudo docker run p 53160 53160 p 53160 53160 udp p
  • 从 iOS 应用程序上的 UDP 服务器接收数据无法在 Linux 服务器上工作,但可以在 macbook pro 上工作 [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 背景 我做
  • 在不使用环回网络的情况下将数据包转发到同一主机中的服务

    我有这个 libnetfilter queue 应用程序 它根据某些 iptables 规则从内核接收数据包 在直接讨论我的问题之前 我提供了一个示例可行代码和其他工具来设置测试环境 以便我们的问题定义和可能的解决方案可以更加准确和稳健 以
  • 使用.Net Core创建UDP套接字

    如何创建一个 UDP 套接字以非阻塞方式接收本地端点中的数据 我不知道数据来自的远程端口 我在 Linux 中使用 NET Core 我认为我可以使用 ReceiveAsync 但它似乎无法以这种方式工作 我这样解决了这个问题 static
  • GCDAsyncUDPSocket源地址返回null

    谷歌代码问题镜像 https groups google com forum topic cocoaasyncsocket grhjZSMLr3U https groups google com forum topic cocoaasync
  • 什么是 STUN?它是否需要端口转发服务器?

    我对没有基础服务器的 p2p 通信进行了一些研究 并通过了 STUN 据我所知 STUN 是 NAT 打孔 的一种方式 不需要对等方进行端口转发即可连接 这是正确的吗 打孔到底是什么意思 这一切看起来都很脆弱 因为如果不需要端口转发 它就会
  • UdpClient 在广播地址上接收

    在 c 中 我使用 UdpClient Receive 函数 public void StartUdpListener Object state try udpServer new UdpClient new IPEndPoint IPAd
  • 简单的udp代理解决方案

    我正在寻找可以代理我的 udp 数据包的解决方案 我有一个客户端向服务器发送 udp 数据包 它们之间的连接非常糟糕 导致大量数据包丢失 一种解决方案是使用一个新的代理服务器 它将所有数据包从客户端重定向到目标服务器 新的代理服务器与这两个
  • 用于接收 UDP 数据包的可变大小缓冲区

    我有一个 UDP 套接字 它将接收一些可能不同大小的数据包 并且我异步处理它 socket async receive from boost asio buffer buffer 65536 senderEndpoint handler 这
  • 通过 Internet 发送 UDP 数据包

    我正在尝试了解 P2P 去中心化网络的一些细节 我的问题如下 假设我有两台名为 comp1 和 comp2 的机器 现在 comp1 设置在我的家庭网络中的路由器后面 comp2 位于我的办公室中 也位于路由器后面 我是否可以像这样在 In
  • HTTP 是否使用 UDP?

    这可能是一个愚蠢的问题 HTTP 是否使用过用户数据报协议 例如 如果使用 HTTP 传输 MP3 或视频 它内部是否使用 UDP 进行传输 From RFC 2616 http www ietf org rfc rfc2616 txt 通
  • 当网络上的所有计算机都具有相同的公共IP地址时,如何向特定计算机发送UDP数据包? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 这就是问题 它非常简单 理解 我家里有 2 台电脑 它们都有相同的公共 IP 地址 例如 1 2 3 4 我在咖啡馆有一台计算机 不同的网络 因此它具
  • 如何监听任意端口的广播包?

    使用 NET 如何在任何端口上侦听发送到 255的udp广播数据包 而不需要绑定到特定端口 我自己找到了办法 它是这样工作的 mainSocket new Socket AddressFamily InterNetwork SocketTy
  • Java UDP 服务器,并发客户端

    下面的代码足以接受并发 UDP 传输吗 更具体地说 如果 2 个客户端同时传输 当我调用 receive 时 DatagramSocket 会将传输排队并一一传送它们 还是只有一个能够通过 DatagramSocket socket new
  • 我刚刚在哪个适配器上收到此 UDP 数据包?

    我正在尝试用 C 编写一个 BOOTP 服务器 我正在接收并解析来自客户端的 BOOTP 数据包 我需要回复我的服务器 IP 地址 问题是 计算机可以有多个网络适配器 客户端还没有 IP 地址 有什么方法可以查出 UDP 数据包是在哪个适配
  • C++ UDP Socket端口复用

    如何在 C 中创建客户端 UDP 套接字 以便它可以侦听另一个应用程序正在侦听的端口 换句话说 如何在 C 中应用端口复用 我只想监听一个端口 您可以使用嗅探器来做到这一点 只需忽略来自不同端口的数据包即可 我可能需要阻止它发送一些特定的数
  • 在 Perl 中如何接受多个 TCP 连接?

    我对 Linux 的 Perl 脚本有疑问 它的主要目的是成为 3 个应用程序之间的中间人 它应该做什么 它应该能够等待 UDP 文本 不带空格 udp port 当它收到 UDP 文本时 它应该将其转发到连接的 TCP 客户端 问题是我的
  • Windows 操作系统中无法访问的 IP 套接字关闭时间

    这些代码通过用户数据报协议提供发送数据 下面有两个代码 当我使用第一个代码来处理无法访问的 IP 地址时 我得到了三秒的延迟 请查看新结果标题 只需打开新的 C 控制台应用程序并将这些代码粘贴到其中 第一个代码 using System u

随机推荐

  • Windows下Cmake安装步骤详解(图文)

    文章目录 Cmake介绍Cmake下载及安装 Cmake介绍 CMake是一个跨平台的安装 xff08 编译 xff09 工具 xff0c 可以用简单的语句来描述所有平台的安装 编译过程 xff0c 并且输出对应的makefile或者pro
  • C语言:通过指针模拟实现strcat函数

    模拟实现strcat strcat函数的功能 把src所指向的字符串 xff08 包括 0 xff09 复制到dest所指向的字符串后面 xff08 删除dest原来末尾的 0 xff09 要保证dest足够长 xff0c 以容纳被复制进来
  • C语言中将字符串拆分再进行拼接

    我们有时候需要对于字符串进行操作 xff0c 主要用到strcat和strtok两个函数 xff0c 因此记录下这次的操作方式以便之后查阅 span class token macro property span class token d
  • 并行编程实现矩阵乘法优化

    实现四种矩阵乘法程序 xff0c 并对比运行效率 1 xff09 串行算法 2 xff09 Catch优化 3 xff09 SSE版本 4 xff09 分片策略 span class token macro property span cl
  • c++的函数reserve()和unique()和sort()

    函数reserve span class token comment vector reserve span span class token macro property span class token directive keywor
  • 关于c中代码加 ‘\‘ 进行换行的说明

    我们在c与c 43 43 中经常会遇到一种情况就是加 进行换行来保持代码整体结构一致的使用情况 xff0c 那么具体来说换行的规则是什么 xff0c 这里进行一下记录 span class token macro property span
  • git的命令总结

    先把清单列出来git cheat sheet git 命令总结 git的init和git clonegit add和git commit 提交二连git checkout 反向操作git reset 回退HEAD指针git revert 同
  • 宏定义中的可变参数 __VA_ARGS__ 用法 与 #和##的用法

    首先了解一下可变参数 span class token macro property span class token directive keyword include span span class token string lt st
  • C++结构体简单链表原理解释

    对结构体简单链表原理的简单解释 xff0c 程序如下 xff1a struct lianbiao int no string name struct lianbiao next lianbiao head 61 nullptr tail 6
  • linux小连招

    Linux命令目录 查看当前shell的种类find命令查找文件 查看当前shell的种类 查看当前发行版可以使用的shell xff1a chao 64 chao span class token function cat span et
  • 侵略性奶牛(对于二分的总结)

    题目 Farmer John has built a new long barn with N 2 lt 61 N lt 61 100 000 stalls The stalls are located along a straight l
  • To Fill or Not to Fill(贪心算法)

    题目描述 有了高速公路 xff0c 开车从杭州到任何其他城市都很容易 但由于汽车的油箱容量有限 xff0c 我们必须不时地在路上找到加油站 不同的加油站可能会给出不同的价格 你被要求仔细设计最便宜的路线去 输入描述 对于每个测试实例 第一行
  • cmake语法

    目录 基本语法命令行projectadd executabletarget sourcessetfileadd librarymessagetarget link librariestarget include directoriesfin
  • 《C++个人学习笔记》使用cout或cin显示未定义标识符

    在vs自动生成的c 43 43 项目中 xff0c 初次使用cout或cin报未定义标识符错误 xff0c 是由于未声明命名空间的原因 解决方法 xff1a 在头文件中声明全局命名空间 加入 using namespace std 表示使用
  • rosbag error

    rosbag play 报错 error 1 md5sum span class token punctuation span span class token constant ERROR span span class token pu
  • CMake实践(三)静态库和动态库构建

    本节的任务是 xff1a 建立一个静态库和动态库 xff0c 提供HelloFunc函数供其他程序使用 xff0c HelloFunc函数向终端输出Hello World字符串 安装头文件和共享库 1 准备工作 在 backup cmake
  • checksum算法详细的计算方法、实现思路与python校验验证

    1 checksum是什么 xff1f Checksum xff1a 电脑 总和检验码 xff0c 校验和 在数据处理和数据通信领域中 xff0c 用于校验目的的一组数据项的和 这些数据项可以是数字或在计算检验总和过程中看作数字的其它字符串
  • java循环标号

    在Java中 xff0c 要想跳出多重循环 xff0c 可以在外面的循环语句前定义一个标号 xff0c 然后在里层循环体的代码中使用带有标号的break 语句 xff0c 即可跳出外层循环 switch xff08 continue和bre
  • SQL Server安装提示【需要microsoft.NET Framework 3.5 Service Pack 1】

    问题 我在自己电脑安装SQL Server 2014 的时候遇到了这个问题 xff0c SQL Server安装提示 需要microsoft NET Framework 3 5 Service Pack 1 xff1a 解决方法 1 打开控
  • zcu102_12_Standalone以太网数据的UDP传输

    本文在PS的Standalone程序中使用lwip库通过UDP协议实现网络数据传输 包含UDP Server和UDP Client两种形式 本文主要参考lwip的SDK内部说明和工程模板 xff0c xapp1026 xapp1306 SD