【Linux 应用】网络相关开发---ip、网关、掩码、dns、mac的获取和设置,以及dhcp动态获取

本文主要是介绍【Linux 应用】网络相关开发---ip、网关、掩码、dns、mac的获取和设置,以及dhcp动态获取,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近开始调试Linux 的测试版,需要开发网络设置相关功能。其实这一块以前也做过,但是都忘记了,可见沉淀的重要性。


1、ip、掩码设置和获取

通过int ioctl(int d, int request, ...);这个函数可以获取到。

其中:

IP设置:SIOCGIFADDR

掩码设置:SIOCGIFNETMASK

mac设置:SIOCGIFHWADDR

其他具体如下:

2、DNS获取和设置

dns设置和获取时通过读写/etc/resolv.conf文件来实现的

# cat /etc/resolv.conf 
nameserver 202.96.134.133
nameserver 202.96.128.166
nameserver 202.96.134.133 # eth0
nameserver 202.96.128.166 # eth0

/tmp/resolv.conf文件也是可以的

# ls -l /etc/resolv.conf 
lrwxrwxrwx    1 root     root            18 Apr 22  2020 /etc/resolv.conf -> ../tmp/resolv.conf

3、网关获取

通过ip route 命令来获取route,以及字符串处理来获取默认网关(default)

4、dhcp动态获取

通过udhcpc 命令来实现dhcp动态获取的

5、代码实现

1、头文件

#ifndef __NET_MANAGER_H__
#define __NET_MANAGER_H__#define DEFAULT_ETH "eth0"
#define IP_ADDE_COUNT 16#define IP_SET_STATIC   1
#define IP_SET_AUTO     0int start_dhcp(char* net_name);
int end_dhcp();int is_valid_netmask(char* netmask);int get_ip(char* ip,int length);
int get_ip_netmask(char* ip,int length);int get_mac(char* addr,int length);int set_ip_netmask(char* ip,int length);
int set_ip(char* ip,int length);int set_gateway(char* gateway,int length);
int get_gateway(char* gateway, int length);
int get_dns(char* dns1, int length_dns1, char* dns2, int length_dns2);
int set_dns(const char *dns1,int length_dns1, const char *dns2, int length_dns2);
void set_net(char *ip_addr,int length_ip_addr,char *netmask,int length_netmask,char *gateway,int length_gateway,char *dns1,int length_dns1,char *dns2,int length_dns2);
int connect_check_real ();
int device_check_if_conn(char* ifname);
void net_init();
#endif

2、实现文件

#include <sys/socket.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <ctype.h>
#include <net/route.h>
#include <fcntl.h>
#include <string.h>
#include <pthread.h>
#include <sys/wait.h>
#if defined(__GLIBC__) && __GLIBC__ >=2 && __GLIBC_MINOR__ >= 1
#include <netpacket/packet.h>
#include <net/ethernet.h>
#else
#include <sys/types.h>
#include <netinet/if_ether.h>
#endif#include "netManager.h"
#include "userInfo.h"
#include "debugUtils.h"#define NET_MANAGER_FALSE -1
#define NET_MANAGER_TRUE 0static int set_addr(char* ip, int flag);
static int get_addr(char *addr, int length, int flag);/*
*检测ips是否合法
*/
static int is_valid_ip(const char* ipaddr)
{int ret = 0;struct in_addr inp;char buf[64] = {0};int ip1,ip2,ip3,ip4;if(ipaddr == NULL){printf("is_valid_ip error: ipaddr is NULL \n");return NET_MANAGER_FALSE;}sscanf(ipaddr, "%03d.%03d.%03d.%03d", &ip1,&ip2,&ip3,&ip4);snprintf((char *)buf, sizeof(buf), "%d.%d.%d.%d", ip1, ip2, ip3, ip4);ret = inet_aton(buf, &inp);if (0 == ret){return NET_MANAGER_FALSE;}return NET_MANAGER_TRUE;
}/** 先验证是否为合法IP,然后将掩码转化�?2无符号整型,取反�?00...00111...1�?* 然后再加1�?0...01000...0,此时为2^n,如果满足就为合法掩�?** */
int is_valid_netmask(char* netmask)
{if(netmask == NULL){printf("is_valid_ip error: ipaddr is NULL \n");return NET_MANAGER_FALSE;}if(is_valid_ip(netmask) == 0){unsigned long b = 0, i, n[4];sscanf(netmask, "%u.%u.%u.%u", &n[3], &n[2], &n[1], &n[0]);for(i = 0; i < 4; ++i) //将子网掩码存�?2位无符号整型{b += n[i] << (i * 8);}b = ~b + 1;if((b & (b - 1)) == 0) //判断是否�?^nreturn NET_MANAGER_TRUE;}GUI_DEBUG("============is_valid_netmask=======%s=============\n",netmask);return NET_MANAGER_FALSE;
}int end_dhcp()
{int ret = NET_MANAGER_FALSE;if(access("/var/run/udhcpc.pid",R_OK) == -1){return NET_MANAGER_TRUE;}ret = system("cat /var/run/udhcpc.pid|xargs kill -9");if(ret < 0){perror("end_dhcp error");return NET_MANAGER_FALSE;}return NET_MANAGER_TRUE;
}/*
*dhcp动态获取网络
*/
int start_dhcp(char* net_name)
{int ret = NET_MANAGER_FALSE;char cmd[IP_ADDE_COUNT+128] = {0};end_dhcp();if(NULL == net_name ||strlen(net_name) == 0){snprintf(cmd, sizeof(cmd),"busybox udhcpc -b -q -i %s -s /etc/simple.script -p /var/run/udhcpc.pid",DEFAULT_ETH);cmd[sizeof(cmd) -1] ='\0';}else{snprintf(cmd, sizeof(cmd),"busybox udhcpc -b -q -i %s -s /etc/simple.script -p /var/run/udhcpc.pid",net_name);cmd[sizeof(cmd) -1] ='\0';}ret = system(cmd);if(ret==-1){GUI_DEBUG("run system command error");}else{if(WIFEXITED(ret)){if(0==WEXITSTATUS(ret)){GUI_DEBUG("cmd: %s", cmd);ret=NET_MANAGER_TRUE;}else{//GLOG_DEBUG("%s connect to internet fail", ifname);}}else{GUI_DEBUG("exit Code status %d", WEXITSTATUS(ret));}}return ret;
}/*
*获取ip
*/
int get_ip(char* ip,int length)
{return get_addr(ip, length, SIOCGIFADDR);
}/*
*获取子网掩码
*/
int get_ip_netmask(char* ip,int length)
{return get_addr(ip, length, SIOCGIFNETMASK);
}/*
*获取mac
*/
int get_mac(char* addr,int length)
{return get_addr(addr, length, SIOCGIFHWADDR);
}/*
*根据参数获取�?
*/
static int get_addr(char *addr, int length, int flag)
{int sockfd = 0;struct sockaddr_in *sin;struct ifreq ifr;if(addr == NULL){printf("get_addr error:addr is NULL\n");return NET_MANAGER_FALSE;}if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){perror("socket error!\n");return NET_MANAGER_FALSE;}memset(&ifr, 0, sizeof(ifr));snprintf(ifr.ifr_name, (sizeof(ifr.ifr_name) - 1), "%s", DEFAULT_ETH);if(ioctl(sockfd, flag, &ifr) < 0 ){perror("ioctl error!\n");close(sockfd);return NET_MANAGER_FALSE;}close(sockfd);if (SIOCGIFHWADDR == flag){memcpy((void *)addr, (const void *)&ifr.ifr_ifru.ifru_hwaddr.sa_data, 6);GUI_DEBUG("mac address: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", addr[0],addr[1],addr[2],addr[3],addr[4],addr[5]);}else{sin = (struct sockaddr_in *)&ifr.ifr_addr;//snprintf((char *)addr, IP_ADDE_COUNT, "%s", inet_ntoa(sin->sin_addr));long ipaddr = inet_addr(inet_ntoa(sin->sin_addr));snprintf((char *)addr, length, "%03d.%03d.%03d.%03d", (ipaddr >> 0) & 0xFF, (ipaddr >> 8) & 0xFF, (ipaddr >> 16) & 0xFF, (ipaddr >> 24) & 0xFF);GUI_DEBUG("============get_addr======= %s =============\n", addr);if(is_valid_ip(addr) != 0){return NET_MANAGER_FALSE;}}return NET_MANAGER_TRUE;
}/*
*设置子网掩码
*/
int set_ip_netmask(char* ip,int length)
{int ip1,ip2,ip3,ip4;if(NULL == ip){printf("set_ip_netmask error: ip is NULL \n");return NET_MANAGER_FALSE;}sscanf(ip, "%03d.%03d.%03d.%03d", &ip1,&ip2,&ip3,&ip4);snprintf((char *)ip, length, "%d.%d.%d.%d", ip1, ip2, ip3, ip4);GUI_DEBUG("============set_ip_netmask======= %s =============\n", ip);return set_addr(ip, SIOCSIFNETMASK);
}/*
*设置ip
*/
int set_ip(char* ip,int length)
{int ip1,ip2,ip3,ip4;if(NULL == ip){printf("set_ip_netmask error: ip is NULL \n");return NET_MANAGER_FALSE;}sscanf(ip, "%03d.%03d.%03d.%03d", &ip1,&ip2,&ip3,&ip4);snprintf((char *)ip, length, "%d.%d.%d.%d", ip1, ip2, ip3, ip4);GUI_DEBUG("============set_ip======= %s =============\n", ip);return set_addr(ip, SIOCSIFADDR);
}/*
*根据参数设置
*/
static int set_addr(char* ip, int flag)
{struct ifreq ifr;struct sockaddr_in sin;int sockfd;if(ip == NULL){printf("set_addr error: ip is NULL\n");return NET_MANAGER_FALSE;}if (is_valid_ip(ip) != 0){printf("ip was invalid!\n");return NET_MANAGER_FALSE;}sockfd = socket(AF_INET, SOCK_DGRAM, 0);if(sockfd == -1){fprintf(stderr, "Could not get socket.\n");perror("eth0\n");return NET_MANAGER_FALSE;}snprintf(ifr.ifr_name, (sizeof(ifr.ifr_name) - 1), "%s", DEFAULT_ETH);/* Read interface flags */if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {fprintf(stderr, "ifdown: shutdown ");perror(ifr.ifr_name);close(sockfd);return NET_MANAGER_FALSE;}memset(&sin, 0, sizeof(struct sockaddr));sin.sin_family = AF_INET;inet_aton(ip, &sin.sin_addr.s_addr);memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr));if (ioctl(sockfd, flag, &ifr) < 0){fprintf(stderr, "Cannot set IP address. ");perror(ifr.ifr_name);close(sockfd);return NET_MANAGER_FALSE;}close(sockfd);return NET_MANAGER_TRUE;
}  /*
*设置网关
*/
int set_gateway(char* gateway,int length)
{int s;struct rtentry rt;struct sockaddr_in sockaddr;int ip1,ip2,ip3,ip4;if((NULL == gateway) || (length == 0)){printf("set_gateway: gateway error.\n");return NET_MANAGER_FALSE;}sscanf(gateway, "%03d.%03d.%03d.%03d", &ip1,&ip2,&ip3,&ip4);snprintf((char *)gateway, length, "%d.%d.%d.%d", ip1, ip2, ip3, ip4);GUI_DEBUG("============set_gateway======= %s =============\n", gateway);s = socket(AF_INET, SOCK_DGRAM, 0);if (s < 0){perror("Socket create error.\n");return NET_MANAGER_FALSE;}memset(&rt, 0, sizeof(struct rtentry));memset(&sockaddr, 0, sizeof(struct sockaddr_in));sockaddr.sin_family = AF_INET;sockaddr.sin_port = 0;if(inet_aton(gateway, &sockaddr.sin_addr)<0){perror("inet_aton error\n" );close(s);return NET_MANAGER_FALSE;}memcpy ( &rt.rt_gateway, &sockaddr, sizeof(struct sockaddr_in));((struct sockaddr_in *)&rt.rt_dst)->sin_family=AF_INET;((struct sockaddr_in *)&rt.rt_genmask)->sin_family=AF_INET;rt.rt_flags = RTF_GATEWAY;if (ioctl(s, SIOCADDRT, &rt)<0){perror("ioctl(SIOCADDRT) error in set_default_route\n");close(s);return NET_MANAGER_FALSE;}close(s);return NET_MANAGER_TRUE;
}/*
*获取网关
*/
int get_gateway(char* gateway, int length)
{   FILE *fp;char buf[512];char cmd[128];char *tmp;   if(gateway == NULL){printf("get_gateway error: gateway is NULL\n");return NET_MANAGER_FALSE;}strcpy(cmd, "busybox ip route");   fp = popen(cmd, "r");   if(NULL == fp)   {   perror("popen error");   return NET_MANAGER_FALSE;   }   while(fgets(buf, sizeof(buf), fp) != NULL)   {   tmp =buf;   while(*tmp && isspace(*tmp))   ++ tmp;   if(strncmp(tmp, "default", strlen("default")) == 0){GUI_DEBUG("default gateway:%s\n", buf);sscanf(buf, "%*s%*s%s", gateway);long ipaddr = inet_addr(gateway);snprintf((char *)gateway, length, "%03d.%03d.%03d.%03d", (ipaddr >> 0) & 0xFF, (ipaddr >> 8) & 0xFF, (ipaddr >> 16) & 0xFF, (ipaddr >> 24) & 0xFF);GUI_DEBUG("default gateway:%s\n", gateway);break;  } }pclose(fp);return NET_MANAGER_TRUE;
}/*
*获取dns
*/
int get_dns(char* dns1, int length_dns1, char* dns2, int length_dns2)
{   FILE *fp;char buf[512];char cmd[128];int i = 0;if(dns1 == NULL || NULL == dns2){printf("get_dns error: dns is NULL \n");return NET_MANAGER_FALSE;}strcpy(cmd, "cat /tmp/resolv.conf");fp = popen(cmd, "r");if(NULL == fp){   perror("popen error");return NET_MANAGER_FALSE;}while(fgets(buf, sizeof(buf), fp) != NULL){if(strlen(buf) == 0 || strncmp(buf, "nameserver",strlen("nameserver")) != 0){continue;}if(i >= 2){i = 0;}if(i == 0){sscanf(buf, "%*s%s", dns1);long ipaddr = inet_addr(dns1);snprintf((char *)dns1, length_dns1, "%03d.%03d.%03d.%03d", (ipaddr >> 0) & 0xFF, (ipaddr >> 8) & 0xFF, (ipaddr >> 16) & 0xFF, (ipaddr >> 24) & 0xFF);}else{sscanf(buf, "%*s%s", dns2);long ipaddr = inet_addr(dns2);snprintf((char *)dns2, length_dns2, "%03d.%03d.%03d.%03d", (ipaddr >> 0) & 0xFF, (ipaddr >> 8) & 0xFF, (ipaddr >> 16) & 0xFF, (ipaddr >> 24) & 0xFF);}i++;}pclose(fp);return NET_MANAGER_TRUE;
} /*
*设置dns
*/
int set_dns(const char *dns1,int length_dns1, const char *dns2, int length_dns2)
{int ret = NET_MANAGER_TRUE;char cmd[128] = {0};int ip1,ip2,ip3,ip4;if(NULL == dns1 || NULL == dns2){printf("set_dns error: dns1 or dns2 is NULL \n");return NET_MANAGER_FALSE;}sscanf(dns1, "%03d.%03d.%03d.%03d", &ip1,&ip2,&ip3,&ip4);snprintf((char *)dns1, length_dns1,"%d.%d.%d.%d", ip1, ip2, ip3, ip4);sscanf(dns2, "%03d.%03d.%03d.%03d", &ip1,&ip2,&ip3,&ip4);snprintf((char *)dns2, length_dns2,"%d.%d.%d.%d", ip1, ip2, ip3, ip4);GUI_DEBUG("============set_dns====dns1=== %s =============\n", dns1);GUI_DEBUG("============set_dns====dns2=== %s =============\n", dns2);if(sizeof(dns1) == 0){return;}snprintf(cmd, sizeof(cmd),"echo \"nameserver %s\" > /tmp/resolv.conf",dns1);ret = system(cmd);if(ret < 0){perror("route error");return NET_MANAGER_FALSE;}snprintf(cmd, sizeof(cmd), "echo \"nameserver %s\" >> /tmp/resolv.conf",dns2);//strcpy(cmd, "route add default gw ");//strcat(cmd, szGateWay);ret = system(cmd);   if(ret < 0)   {   perror("set_dns error");   return NET_MANAGER_FALSE;   }return ret;   
} /*
*设置静态IP网络
*/
void set_net(char *ip_addr,int length_ip_addr,char *netmask,int length_netmask,char *gateway,int length_gateway,char *dns1,int length_dns1,char *dns2,int length_dns2)
{if(ip_addr != NULL){set_ip(ip_addr,length_ip_addr);}if((netmask == NULL) && is_valid_netmask(netmask) == 0){set_ip_netmask(netmask, length_netmask);}else{GUI_DEBUG("g_mask_addr is error\n");}if(gateway != NULL){set_gateway(gateway, length_gateway);}if((dns1 != NULL) && (dns2 != NULL)){set_dns(dns1, length_dns1, dns2, length_dns2);}return;
}void net_init()
{IpInfo_S netInfo = getIpinfo();if(netInfo.m_netMode == IP_SET_STATIC){GUI_DEBUG("net_init is IP_SET_STATIC\n");set_net(netInfo.m_ipAddr, strlen(netInfo.m_ipAddr), netInfo.m_Netmask, strlen(netInfo.m_Netmask), netInfo.m_gateWay, strlen(netInfo.m_gateWay), netInfo.m_Dns1,strlen(netInfo.m_Dns1), netInfo.m_Dns2,strlen(netInfo.m_Dns2));}else{GUI_DEBUG("net_init is IP_SET_AUTO\n");start_dhcp(DEFAULT_ETH);}return;
}int connect_check_real ()
{  int ret = -1;int fp;char status[10];//一定要只读模式打开,读写模式打开不可以  fp = open ("/sys/class/net/eth0/operstate",O_RDONLY);if (fp<0) {printf("open file operstate failure%d\n",fp);return;}memset(status,0,sizeof(status));ret = read (fp,status,10);printf("status:%s\n",status);if (NULL != strstr(status,"up")){printf("on line now \n");ret = 0;}else if (NULL != strstr(status,"down")){printf("off off \n");}else{printf("unknow error\n");}close (fp);return ret;
}int device_check_if_conn(char* ifname)
{pid_t status;uint8_t ret=-1, i=0;char cmd[256];char serverip[3][32]={"114.114.114.114","8.8.8.8","223.5.5.5"};for(i=0;i<3;i++){snprintf(cmd, sizeof(cmd),"busybox ping -I %s -w 1 -c 1 %s 1>/dev/null 2>&1", ifname, serverip[i]);status=system(cmd);if(status==-1){GUI_DEBUG("run system command error");}else{if(WIFEXITED(status)){if(0==WEXITSTATUS(status)){GUI_DEBUG("%s connect to internet ok", ifname);GUI_DEBUG("cmd: %s", cmd);ret=0;break;}else{//GLOG_DEBUG("%s connect to internet fail", ifname);}}else{GUI_DEBUG("exit Code status %d", WEXITSTATUS(status));}}}return ret;
}int check_net()
{if(connect_check_real() != 0){return -1;}if(device_check_if_conn("eth0") != 0){return 0;}return 1;
}

3、测试代码

#include <stdio.h>
#include "netManager.h"void set_net();int main(int argc, char *argv[])
{set_net();get_dhcp(NULL);get_net_info();return 0;
}void set_net()
{char g_mask_addr[IP_ADDE_COUNT] = "255.255.0.0";char g_ip_addr[IP_ADDE_COUNT] = "172.30.16.68";char g_gateway_addr[IP_ADDE_COUNT] = "172.30.15.253";char g_dns_addr[2][IP_ADDE_COUNT] = {"8.8.8.8","114.114.114.144"};set_ip(g_ip_addr);if(is_valid_netmask(g_mask_addr) == 0){set_ip_netmask(g_mask_addr);}else{printf("g_mask_addr is error\n");}set_gateway(g_gateway_addr);set_dns(g_dns_addr[0],g_dns_addr[1]);return;
}void get_net_info()
{char s_ip_addr[IP_ADDE_COUNT] = {0},s_mask_addr[IP_ADDE_COUNT] = {0},s_mac_addr[6] = {0}, \s_gateway_addr[IP_ADDE_COUNT] = {0},s_dns_addr[2][IP_ADDE_COUNT] = {0};get_ip(s_ip_addr);get_mac(s_mac_addr);get_ip_netmask(s_mask_addr);get_gateway(s_gateway_addr);get_dns(s_dns_addr);printf("=========================%s=====================\n",s_ip_addr);printf("=========================%s=====================\n",s_mask_addr);printf("=========================%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x=====================\n", s_mac_addr[0],s_mac_addr[1],s_mac_addr[2],s_mac_addr[3],s_mac_addr[4],s_mac_addr[5]);printf("=========================%s=====================\n",s_gateway_addr);printf("=========================%s=====================\n",s_dns_addr[0]);printf("=========================%s=====================\n",s_dns_addr[1]);return;
}

结束语

这篇文章主要是记录一下,方便以后回忆和查阅,写的不尽详细,又不懂得欢迎留言交流。

这篇关于【Linux 应用】网络相关开发---ip、网关、掩码、dns、mac的获取和设置,以及dhcp动态获取的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/944343

相关文章

Python标准库之数据压缩和存档的应用详解

《Python标准库之数据压缩和存档的应用详解》在数据处理与存储领域,压缩和存档是提升效率的关键技术,Python标准库提供了一套完整的工具链,下面小编就来和大家简单介绍一下吧... 目录一、核心模块架构与设计哲学二、关键模块深度解析1.tarfile:专业级归档工具2.zipfile:跨平台归档首选3.

Oracle数据库定时备份脚本方式(Linux)

《Oracle数据库定时备份脚本方式(Linux)》文章介绍Oracle数据库自动备份方案,包含主机备份传输与备机解压导入流程,强调需提前全量删除原库数据避免报错,并需配置无密传输、定时任务及验证脚本... 目录说明主机脚本备机上自动导库脚本整个自动备份oracle数据库的过程(建议全程用root用户)总结

使用IDEA部署Docker应用指南分享

《使用IDEA部署Docker应用指南分享》本文介绍了使用IDEA部署Docker应用的四步流程:创建Dockerfile、配置IDEADocker连接、设置运行调试环境、构建运行镜像,并强调需准备本... 目录一、创建 dockerfile 配置文件二、配置 IDEA 的 Docker 连接三、配置 Do

Linux如何查看文件权限的命令

《Linux如何查看文件权限的命令》Linux中使用ls-R命令递归查看指定目录及子目录下所有文件和文件夹的权限信息,以列表形式展示权限位、所有者、组等详细内容... 目录linux China编程查看文件权限命令输出结果示例这里是查看tomcat文件夹总结Linux 查看文件权限命令ls -l 文件或文件夹

idea的终端(Terminal)cmd的命令换成linux的命令详解

《idea的终端(Terminal)cmd的命令换成linux的命令详解》本文介绍IDEA配置Git的步骤:安装Git、修改终端设置并重启IDEA,强调顺序,作为个人经验分享,希望提供参考并支持脚本之... 目录一编程、设置前二、前置条件三、android设置四、设置后总结一、php设置前二、前置条件

深入浅出SpringBoot WebSocket构建实时应用全面指南

《深入浅出SpringBootWebSocket构建实时应用全面指南》WebSocket是一种在单个TCP连接上进行全双工通信的协议,这篇文章主要为大家详细介绍了SpringBoot如何集成WebS... 目录前言为什么需要 WebSocketWebSocket 是什么Spring Boot 如何简化 We

Java Stream流之GroupBy的用法及应用场景

《JavaStream流之GroupBy的用法及应用场景》本教程将详细介绍如何在Java中使用Stream流的groupby方法,包括基本用法和一些常见的实际应用场景,感兴趣的朋友一起看看吧... 目录Java Stream流之GroupBy的用法1. 前言2. 基础概念什么是 GroupBy?Stream

python设置环境变量路径实现过程

《python设置环境变量路径实现过程》本文介绍设置Python路径的多种方法:临时设置(Windows用`set`,Linux/macOS用`export`)、永久设置(系统属性或shell配置文件... 目录设置python路径的方法临时设置环境变量(适用于当前会话)永久设置环境变量(Windows系统

python中列表应用和扩展性实用详解

《python中列表应用和扩展性实用详解》文章介绍了Python列表的核心特性:有序数据集合,用[]定义,元素类型可不同,支持迭代、循环、切片,可执行增删改查、排序、推导式及嵌套操作,是常用的数据处理... 目录1、列表定义2、格式3、列表是可迭代对象4、列表的常见操作总结1、列表定义是处理一组有序项目的

PyQt5 GUI 开发的基础知识

《PyQt5GUI开发的基础知识》Qt是一个跨平台的C++图形用户界面开发框架,支持GUI和非GUI程序开发,本文介绍了使用PyQt5进行界面开发的基础知识,包括创建简单窗口、常用控件、窗口属性设... 目录简介第一个PyQt程序最常用的三个功能模块控件QPushButton(按钮)控件QLable(纯文本