06_W5500_DHCP

1.DHCP协议介绍:

        DHCP(Dynamic Host Configuration Protocol)是一种用于自动分配IP地址和其他网络配置信息的协议。它允许网络中的设备(如计算机、手机、打印机等)在连接到网络时自动获取IP地址、子网掩码、默认网关、DNS服务器等信息,而无需手动配置。

DHCP工作原理是通过DHCP服务器向网络中的设备提供IP地址和其他配置信息。当设备连接到网络时,它会发送一个DHCP请求,请求一个可用的IP地址和其他配置信息。DHCP服务器收到请求后,会分配一个可用的IP地址,并将其他配置信息一并发送给设备,使设备能够顺利地加入到网络中。

DHCP的优点是简化了网络管理,减少了手动配置的工作量,同时也提高了网络的灵活性和可扩展性。通过DHCP,管理员可以更轻松地管理网络中的设备,并且可以更快速地进行网络扩展和变更。

2.DHCP报文

DHCP报文种类:

DHCP一共有8中报文,各种类型报文的基本功能如下:

报文类型说明
Discover(0x01)    DHCP客户端在请求IP地址时并不知道DHCP服务器的位置,因此DHCP客户端会在本地网络内以广播方式发送Discover请求报文,以发现网络中的DHCP服务器。所有收到Discover报文的DHCP服务器都会发送应答报文,DHCP客户端据此可以知道网络中存在的DHCP服务器的位置。
Offer(0x02)DHCP服务器收到Discover报文后,就会在所配置的地址池中查找一个合适的IP地址,加上相应的租约期限和其他配置信息(如网关、DNS服务器等),构造一个Offer报文,发送给DHCP客户端,告知用户本服务器可以为其提供IP地址。但这个报文只是告诉DHCP客户端可以提供IP地址,最终还需要客户端通过ARP来检测该IP地址是否重复。
Request(0x03) DHCP客户端可能会收到很多Offer请求报文,所以必须在这些应答中选择一个。通常是选择第一个Offer应答报文的服务器作为自己的目标服务器,并向该服务器发送一个广播的Request请求报文,通告选择的服务器,希望获得所分配的IP地址。另外,DHCP客户端在成功获取IP地址后,在地址使用租期达到50%时,会向DHCP服务器发送单播Request请求报文请求续延租约,如果没有收到ACK报文,在租期达到87.5%时,会再次发送广播的Request请求报文以请求续延租约。
Decline(0x04)DHCP客户端收到DHCP服务器ACK应答报文后,通过地址冲突检测发现服务器分配的地址冲突或者由于其他原因导致不能使用,则会向DHCP服务器发送Decline请求报文,通知服务器所分配的IP地址不可用,以期获得新的IP地址。
ACK(0x05) DHCP服务器收到Request请求报文后,根据Request报文中携带的用户MAC来查找有没有相应的租约记录,如果有则发送ACK应答报文,通知用户可以使用分配的IP地址。
NAK(0x06如果DHCP服务器收到Request请求报文后,没有发现有相应的租约记录或者由于某些原因无法正常分配IP地址,则向DHCP客户端发送NAK应答报文,通知用户无法分配合适的IP地址。
Release(0x07) 当DHCP客户端不再需要使用分配IP地址时(一般出现在客户端关机、下线等状况)就会主动向DHCP服务器发送RELEASE请求报文,告知服务器用户不再需要分配IP地址,请求DHCP服务器释放对应的IP地址。
Inform(0x08) DHCP客户端如果需要从DHCP服务器端获取更为详细的配置信息,则向DHCP服务器发送Inform请求报文;DHCP服务器在收到该报文后,将根据租约进行查找到相应的配置信息后,向DHCP客户端发送ACK应答报文。目前基本上不用了。
DHCP报文格式:

字段长度说明
op1byte是报文的操作类型,分为请求报文和响应报文,1为请求报文;2为响应报文。具体的报文类型在option字段中标识。
htype1byte硬件地址的长度,以太网的硬件地址长度为6bytes。
hlen1byte硬件地址的长度,以太网的硬件地址长度为6bytes。
hops1byte表示当前dhcp报文经过的DHCP中继的数目,每经过一个DHCP中继这个字段就加1.
xid4bytes由client端产生的随机数,用于匹配请求和应答报文,就是匹配应答报文是对哪个请求报文做出应答。
secs2bytes客户端进入IP地址申请进程的时间或者更新IP地址进程的时间;由客户端软件根据情况设定。目前没有使用,固定为0。
flags2bytes是标志字段,16比特中只使用了最高位比特(即最左边的比特),这个个比特是广播响应标识位,用来标识DHCP服务器发出的响应报文是广播还是单播,0是单播,1是广播。其余的比特位保留不用,都为0.
ciaddr4bytes是客户端的IP地址,可以是client自己的IP地址,也可以是server分配给client的IP地址。
yiaddr4bytes(Your IP Address),是server分配给client的IP地址。
siaddr4bytes是client端获取IP地址等信息的server端的地址。
giaddr4bytes是client发出请求报文后经过的第一个中继的IP地址。
chaddr16bytes是client端的硬件地址,在client发出报文时会把自己网卡的硬件地址写进这个字段。
sname64bytes服务器主机名,是client端获取IP地址等信息的服务器名称。
file128bytes是client的启动配置文件名,是服务器为client指定的启动配置文件名及路径信息,由服务器填写。
options可变是可选变长的选项字段,这个字段包含了终端的初始配置信息和网络配置信息,包括报文类型,有效租期,DNS服务器的IP地址等配置信息。

2.DHCP流程:

DHCP的流程分为四个阶段:

分别是:

1.发现阶段:DHCP客户端向DHCP服务端发送DHCP_DISCOVER报文。

2.提供阶段:DHCP服务端收到客户端DHCP_DISCOVER报文后,向发送DHCP客户端发送DHCP_OFFER报文,该报文中包含尚未分配的地址信息。

3.选择阶段:DHCP客户端选择IP地址,然后广播发送DHCP_REQUEST包,宣告使用它挑选的DHCP服务器地址并正式请求DHCP服务器分配地址

4.确认阶段:当DHCP服务器收到DHCP客户端的DHCP_REQUEST包后,便向客户端发送包含它所提供的IP地址及其他配置信息的DHCPACK确认包。

3.代码分析:

首先初始化单片机的外设:时钟、spi、uart、24c02、配置w5500参数等。

然后调用函数:init_dhcp_client函数对DHCP进行初始化,主要设置ip、mac等信息,把dhcp_state状态设置为STATE_DHCP_READY

void init_dhcp_client(void)
{uint8 txsize[MAX_SOCK_NUM] = {2, 2, 2, 2, 2, 2, 2, 2};uint8 rxsize[MAX_SOCK_NUM] = {2, 2, 2, 2, 2, 2, 2, 2};//uint8 ip_broadcast[4]={255,};uint8 ip_0[4] = {0,};DHCP_XID = 0x12345678;memset(OLD_SIP, 0, sizeof(OLD_SIP));memset(DHCP_SIP, 0, sizeof(DHCP_SIP));memset(DHCP_REAL_SIP, 0, sizeof(GET_SN_MASK));iinchip_init();setSHAR(ConfigMsg.mac);setSUBR(ip_0);setGAR(ip_0);setSIPR(ip_0);printf("MAC=%02x:%02x:%02x:%02x:%02x:%02x\r\n", DHCP_CHADDR[0], DHCP_CHADDR[1], DHCP_CHADDR[2], DHCP_CHADDR[3], DHCP_CHADDR[4], DHCP_CHADDR[5]);sysinit(txsize, rxsize);//clear ip setted flagdhcp_state = STATE_DHCP_READY;#ifdef _DHCP_DEBUGprintf("init_dhcp_client:%u\r\n", SOCK_DHCP);#endif
}

进入while循环执行DHCP_run()函数

uint8_t DHCP_run(void)
{uint8_t  type;uint8_t  ret;if(dhcp_state == STATE_DHCP_STOP) return DHCP_STOPPED;if(getSn_SR(SOCK_DHCP) != SOCK_UDP)socket(SOCK_DHCP, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00);ret = DHCP_RUNNING;type = parseDHCPMSG();switch ( dhcp_state ){case STATE_DHCP_READY :DHCP_allocated_ip[0] = 0;DHCP_allocated_ip[1] = 0;DHCP_allocated_ip[2] = 0;DHCP_allocated_ip[3] = 0;send_DHCP_DISCOVER();dhcp_time = 0;dhcp_state = STATE_DHCP_DISCOVER;break;case STATE_DHCP_DISCOVER :if (type == DHCP_OFFER){#ifdef _DHCP_DEBUG_printf("> Receive DHCP_OFFER\r\n");#endifDHCP_allocated_ip[0] = pDHCPMSG->yiaddr[0];DHCP_allocated_ip[1] = pDHCPMSG->yiaddr[1];DHCP_allocated_ip[2] = pDHCPMSG->yiaddr[2];DHCP_allocated_ip[3] = pDHCPMSG->yiaddr[3];send_DHCP_REQUEST();dhcp_time = 0;dhcp_state = STATE_DHCP_REQUEST;}elseret = check_DHCP_timeout();break;case STATE_DHCP_REQUEST :if (type == DHCP_ACK){#ifdef _DHCP_DEBUG_printf("> Receive DHCP_ACK\r\n");#endifif (check_DHCP_leasedIP()){// Network info assignment from DHCPprintf("ip:%d.%d.%d.%d\r\n", DHCP_allocated_ip[0], DHCP_allocated_ip[1], DHCP_allocated_ip[2], DHCP_allocated_ip[3]);printf("sn:%d.%d.%d.%d\r\n", DHCP_allocated_sn[0], DHCP_allocated_sn[1], DHCP_allocated_sn[2], DHCP_allocated_sn[3]);printf("gw:%d.%d.%d.%d\r\n", DHCP_allocated_gw[0], DHCP_allocated_gw[1], DHCP_allocated_gw[2], DHCP_allocated_gw[3]);dhcp_ip_assign();reset_DHCP_timeout();dhcp_state = STATE_DHCP_LEASED;}else{// IP address conflict occurredreset_DHCP_timeout();dhcp_ip_conflict();dhcp_state = STATE_DHCP_READY;}}else if (type == DHCP_NAK){#ifdef _DHCP_DEBUG_printf("> Receive DHCP_NACK\r\n");#endifreset_DHCP_timeout();dhcp_state = STATE_DHCP_DISCOVER;}elseret = check_DHCP_timeout();break;case STATE_DHCP_LEASED :ret = DHCP_IP_LEASED;if ((dhcp_lease_time != DEFAULT_LEASETIME) && ((dhcp_lease_time / 2) < dhcp_time)){#ifdef _DHCP_DEBUG_printf("> Maintains the IP address \r\n");#endiftype = 0;OLD_allocated_ip[0] = DHCP_allocated_ip[0];OLD_allocated_ip[1] = DHCP_allocated_ip[1];OLD_allocated_ip[2] = DHCP_allocated_ip[2];OLD_allocated_ip[3] = DHCP_allocated_ip[3];DHCP_XID++;send_DHCP_REQUEST();reset_DHCP_timeout();dhcp_state = STATE_DHCP_REREQUEST;}break;case STATE_DHCP_REREQUEST :ret = DHCP_IP_LEASED;if (type == DHCP_ACK){dhcp_retry_count = 0;if (OLD_allocated_ip[0] != DHCP_allocated_ip[0] ||OLD_allocated_ip[1] != DHCP_allocated_ip[1] ||OLD_allocated_ip[2] != DHCP_allocated_ip[2] ||OLD_allocated_ip[3] != DHCP_allocated_ip[3]){ret = DHCP_IP_CHANGED;dhcp_ip_update();#ifdef _DHCP_DEBUG_printf(">IP changed.\r\n");#endif}#ifdef _DHCP_DEBUG_else printf(">IP is continued.\r\n");#endifreset_DHCP_timeout();dhcp_state = STATE_DHCP_LEASED;}else if (type == DHCP_NAK){#ifdef _DHCP_DEBUG_printf("> Receive DHCP_NACK, Failed to maintain ip\r\n");#endifreset_DHCP_timeout();dhcp_state = STATE_DHCP_DISCOVER;}else ret = check_DHCP_timeout();break;default :break;}return ret;
}

分析DHCP_run函数:

1.  打开socket,调用parseDHCPMSG()函数,接受数据并解析,将收到的数据进行保存。

int8_t parseDHCPMSG(void)//20180625
{uint8_t svr_addr[6];uint16_t  svr_port;uint16_t len;uint8_t * p;uint8_t * e;uint8_t type;uint8_t opt_len;if((len = getSn_RX_RSR(SOCK_DHCP)) > 0){len = recvfrom(SOCK_DHCP, (uint8_t *)pDHCPMSG, len, svr_addr, &svr_port);#ifdef _DHCP_DEBUG_printf("DHCP message : %d.%d.%d.%d(%d) %d received. \r\n", svr_addr[0], svr_addr[1], svr_addr[2], svr_addr[3], svr_port, len);#endif}else return 0;if (svr_port == DHCP_SERVER_PORT){// compare mac addressif ( (pDHCPMSG->chaddr[0] != DHCP_CHADDR[0]) || (pDHCPMSG->chaddr[1] != DHCP_CHADDR[1]) ||(pDHCPMSG->chaddr[2] != DHCP_CHADDR[2]) || (pDHCPMSG->chaddr[3] != DHCP_CHADDR[3]) ||(pDHCPMSG->chaddr[4] != DHCP_CHADDR[4]) || (pDHCPMSG->chaddr[5] != DHCP_CHADDR[5])   )return 0;type = 0;p = (uint8_t *)(&pDHCPMSG->op);//2p = p + 240;      // 240 = sizeof(RIP_MSG) + MAGIC_COOKIE size in RIP_MSG.opt - sizeof(RIP_MSG.opt)e = p + (len - 240);while ( p < e ){switch ( *p ){case endOption :p = e;   // for break while(p < e)break;case padOption :p++;break;case dhcpMessageType :p++;p++;type = *p++;break;case subnetMask :p++;p++;DHCP_allocated_sn[0] = *p++;DHCP_allocated_sn[1] = *p++;DHCP_allocated_sn[2] = *p++;DHCP_allocated_sn[3] = *p++;break;case routersOnSubnet :p++;opt_len = *p++;DHCP_allocated_gw[0] = *p++;DHCP_allocated_gw[1] = *p++;DHCP_allocated_gw[2] = *p++;DHCP_allocated_gw[3] = *p++;p = p + (opt_len - 4);break;case dns :p++;opt_len = *p++;DHCP_allocated_dns[0] = *p++;DHCP_allocated_dns[1] = *p++;DHCP_allocated_dns[2] = *p++;DHCP_allocated_dns[3] = *p++;p = p + (opt_len - 4);break;case dhcpIPaddrLeaseTime :p++;opt_len = *p++;dhcp_lease_time  = *p++;dhcp_lease_time  = (dhcp_lease_time << 8) + *p++;dhcp_lease_time  = (dhcp_lease_time << 8) + *p++;dhcp_lease_time  = (dhcp_lease_time << 8) + *p++;#ifdef _DHCP_DEBUG_//               dhcp_lease_time = 10;//				printf("dhcp_lease_time:%d\r\n",(int)dhcp_lease_time);#endifbreak;case dhcpServerIdentifier :p++;opt_len = *p++;DHCP_SIP[0] = *p++;DHCP_SIP[1] = *p++;DHCP_SIP[2] = *p++;DHCP_SIP[3] = *p++;break;default :p++;opt_len = *p++;p += opt_len;break;} // switch} // while} // ifreturn	type;
}

2.然后进入switch状态机,首先dhcp_state的值为STATE_DHCP_READY,执行一下代码:

进入发现阶段:DHCP客户端向DHCP服务端发送DHCP_DISCOVER报文,然后把dhcp_state的值设为STATE_DHCP_DISCOVER。

 case STATE_DHCP_READY :DHCP_allocated_ip[0] = 0;DHCP_allocated_ip[1] = 0;DHCP_allocated_ip[2] = 0;DHCP_allocated_ip[3] = 0;send_DHCP_DISCOVER();dhcp_time = 0;dhcp_state = STATE_DHCP_DISCOVER;break;

3.然后退出switch,再次调用parseDHCPMSG()函数去接受DHCP服务端发来的数据并解析,再次进入switch状态机中,执行STATE_DHCP_DISCOVER代码,如果数据包的类型是DHCP_OFFER

就执行以下代码:DHCP客户端选择IP地址,然后广播发送DHCP_REQUEST包,宣告使用它挑选的DHCP服务器地址并正式请求DHCP服务器分配地址。

 case STATE_DHCP_DISCOVER :if (type == DHCP_OFFER){#ifdef _DHCP_DEBUG_printf("> Receive DHCP_OFFER\r\n");#endifDHCP_allocated_ip[0] = pDHCPMSG->yiaddr[0];DHCP_allocated_ip[1] = pDHCPMSG->yiaddr[1];DHCP_allocated_ip[2] = pDHCPMSG->yiaddr[2];DHCP_allocated_ip[3] = pDHCPMSG->yiaddr[3];send_DHCP_REQUEST();dhcp_time = 0;dhcp_state = STATE_DHCP_REQUEST;}

 4.如果正确接收到DHCP服务端的DHAP_ACK数据包,则DHCP请求就成功了。执行一下代码:

若是DHAP_ACK数据包,则调用check_DHCP_leasedIP()函数检查IP是否有效,然后我们去设置w5500的IP等信息,把dhcp_state状态设为STATE_DHCP_LEASED,若是DHCP_NAK数据包,调用reset_DHCP_timeout()把超时时间复位, 然后将dhcp_state值改为STATE_DHCP_DISCOVER重新进入发现阶段。

 case STATE_DHCP_REQUEST :if (type == DHCP_ACK){#ifdef _DHCP_DEBUG_printf("> Receive DHCP_ACK\r\n");#endifif (check_DHCP_leasedIP()){// Network info assignment from DHCPprintf("ip:%d.%d.%d.%d\r\n", DHCP_allocated_ip[0], DHCP_allocated_ip[1], DHCP_allocated_ip[2], DHCP_allocated_ip[3]);printf("sn:%d.%d.%d.%d\r\n", DHCP_allocated_sn[0], DHCP_allocated_sn[1], DHCP_allocated_sn[2], DHCP_allocated_sn[3]);printf("gw:%d.%d.%d.%d\r\n", DHCP_allocated_gw[0], DHCP_allocated_gw[1], DHCP_allocated_gw[2], DHCP_allocated_gw[3]);dhcp_ip_assign();reset_DHCP_timeout();dhcp_state = STATE_DHCP_LEASED;}else{// IP address conflict occurredreset_DHCP_timeout();dhcp_ip_conflict();dhcp_state = STATE_DHCP_READY;}}else if (type == DHCP_NAK){#ifdef _DHCP_DEBUG_printf("> Receive DHCP_NACK\r\n");#endifreset_DHCP_timeout();dhcp_state = STATE_DHCP_DISCOVER;}elseret = check_DHCP_timeout();break;

05_W5500_UDP通信 <--------- 上一篇                                                                                                下一篇----------> 07——W5500

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/220653.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaEE:单例模式(饿汉模式和懒汉模式)精讲

前言 什么是单例模式&#xff1f; 其实用通俗的话就是程序猿约定俗成的一些东西&#xff0c;就比如如果你继承了一个抽象类&#xff0c;你就要重写里面的抽象方法&#xff0c;如果你实现了一个接口&#xff0c;你就要重写里面的方法。如果不进行重写&#xff0c;那么编译器就会…

2024上海智慧城市展会(世亚智博会)促进长三角地区智慧城市发展

上海市政府近期印发的《上海市进一步推进新型基础设施建设行动方案(2023-2026年)》标志着新一轮新基建的全面启动。市政府副秘书长、市发展改革委主任顾军指出&#xff0c;这一行动方案紧抓智能算力、大模型、数据要素、区块链、机器人等技术发展趋势和绿色低碳节能要求&#x…

【LeetCode:2132. 用邮票贴满网格图 | 二维前缀和 + 二维差分和】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

达索系统SOLIDWORKS 2024 Visualize新功能

SOLIDWORKS Visualize&#xff08;原名为 Bunkspeed&#xff09;是一整套独立的软件工具&#xff0c;Visualize模块主要是用于对SOLIDWORKS设计出的产品图进行渲染、做动画&#xff0c;方便用户更好的展示、宣传产品&#xff1b;以最快速、最轻松的方式创建专业的照片级图像、动…

基于YOLOv8深度学习的水稻害虫检测与识别系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、深度学习实战

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

《使用ThinkPHP6开发项目》 - 登录接口三【表单验证】

《使用ThinkPHP6开发项目》 - 登录接口一-CSDN博客 https://blog.csdn.net/centaury32/article/details/134974860 在设置用户登录时&#xff0c;由于安全问题会对登录密码进行加密 表单验证这里也可以使用ThinkPHP6自带的验证规则&#xff0c;创建一个验证管理员的文件 ph…

MYSQL各种日志

感谢B站up主的视频分享 黑马程序员 MySQL数据库入门到精通&#xff0c;从mysql安装到mysql高级、mysql优化全囊括_哔哩哔哩_bilibili

2023 亚马逊云科技 re:Invent 大会探秘:Aurora 无限数据库的突破性应用

文章目录 一、前言二、Amazon Aurora 无限数据库2.1 亚马逊云科技数据库产品发展历程2.2 什么是 Amazon Aurora Limitless Database&#xff08;无限数据库&#xff09;2.3 Amazon Aurora Limitless Database 设计架构2.4 Amazon Aurora Limitless Database 分片功能2.5 使用 A…

xtu oj 1194 Recipient

题目描述 快递小哥每天都辛苦的送快递&#xff0c;今天他需要送N份快递给N个收件人&#xff0c;第i份快递需要送给第i个收件人。 请问其中发生恰好K个送错了的情况数是多少&#xff1f; 输入 存在多样例。 每行输入两个整数N和K&#xff0c;1≤N≤1000,0≤K≤N。 如果两个都…

pytorch中的归一化:BatchNorm、LayerNorm 和 GroupNorm

1 归一化概述 训练深度神经网络是一项具有挑战性的任务。 多年来&#xff0c;研究人员提出了不同的方法来加速和稳定学习过程。 归一化是一种被证明在这方面非常有效的技术。 1.1 为什么要归一化 数据的归一化操作是数据处理的一项基础性工作&#xff0c;在一些实际问题中&am…

SpringBoot - 事件机制使用详解(ApplicationEvent、ApplicationListener)

SpringBoot - 事件机制使用详解&#xff08;ApplicationEvent、ApplicationListener&#xff09; Spring 事件机制使用观察者模式来传递事件和消息。我们可以使用 ApplicationEvent 类来发布事件&#xff0c;然后使用 ApplicationListener 接口来监听事件。当事件发生时&#…

程序员月经焦虑 :如何成为高级工程师

高级工程师意味着什么&#xff1f; ChatGPT的回复&#xff1a;高级工程师对编程语言、软件设计原则和开发方法有深刻的理解。 开发方法 开发方法学是旨在使团队有效的组织方法。这些对我们来说可能很无聊&#xff0c;但我们希望你在这方面有专业知识。 我已经对非敏捷开发方法…

SAHI强化YOLOv5在小目标上的表现

文章目录 环境前言安装sahiyolov5检测sahi添加新的检测模型 环境 ubuntu 18.04 64bitsahi 0.8.4yolov5 5.0pytorch 1.7.1cu101 前言 目标检测和实例分割是迄今为止计算机视觉中最重要的应用领域&#xff0c;各种目标检测网络层出不穷&#xff0c;然而&#xff0c;小目标的检…

速卖通(AliExpress)店铺流量怎么转化?自养号测评策略

随着全球电商的蓬勃发展&#xff0c;速卖通&#xff08;AliExpress&#xff09;作为中国领先的跨境电商平台&#xff0c;为卖家提供了一个广阔的销售舞台。然而&#xff0c;对于卖家来说&#xff0c;如何让速卖通店铺实现转化&#xff0c;吸引更多的买家成为关键。 一、速卖通…

javaweb `jdbc.properties`文件编写

问题&#xff1a;查询数据库查不到&#xff0c;大概率是两者编码对应不上&#xff1f; 问题描述&#xff1a; 从数据库查询这一句&#xff0c;但数据库是有这个值的。 解决办法&#xff1a; 这是jdbc.properties里面写的内容 drivercom.mysql.jdbc.Driverurljdbc:mysql://12…

jmeter简单压测kafka

前言 这也是一个笔记&#xff0c;就是计划用jmeter做性能测试&#xff0c;但是这里是只要将数据放到kafka的topic里&#xff0c;后面查看下游业务处理能力。 一、方案 因为只要实现数据放到kafka&#xff0c;参考了下博友的方案&#xff0c;可行。 二、方案验证 详细过程就不…

iptables详解

1、介绍 iptables 是一个在 Linux 系统上用于配置和管理防火墙规则的工具。它允许系统管理员定义数据包的过滤规则、网络地址转换&#xff08;NAT&#xff09;规则和数据包的网络地址和端口的转发规则。iptables 提供了非常灵活和强大的功能&#xff0c;可以用于保护网络安全、…

微服务实战系列之MQ

前言 从今天起&#xff0c;席卷北国的雪&#xff0c;持续了一整天&#xff0c;北京也不例外。这场意外的寒潮&#xff0c;把整个冬天渲染的格外cool。当然你可以在外面打雪仗、堆雪人、拉雪橇&#xff0c;也可以静坐屋内&#xff0c;来一场围炉煮茶的party。此刻&#xff0c;冬…

KUKA机器人如何隐藏程序或程序段?

KUKA机器人如何隐藏程序或程序段? 如下图所示,新建一个示例程序进行说明, 如下图所示,如果红框中的动作指令不想让别人看到,想隐藏起来,如何做到? 如下图所示,在想要隐藏的程序或程序段的前后,分别添加 ;fold 和 endfold指令(这里要注意是英文状态下的输入法), 如…

安卓跳转页面闪屏,方法里需要传View 参数

/*** 跳转到首页的公共方法* */public void ToIndexpage(View v){//设置跳转的页面Intent intent new Intent(this, MainActivity.class);//实行跳转startActivity(intent);}