文档章节

wpa_supplicant与kernel的接口

s
 sflfqx
发布于 2014/09/29 17:07
字数 1669
阅读 410
收藏 0
点赞 0
评论 0

1. 接口定义实现wpa_drivers

 

  wpa_drivers的定义如下:

[cpp] view plaincopy

  1. struct wpa_driver_ops *wpa_drivers[] =  

  2. {  

  3. #ifdef CONFIG_DRIVER_WEXT  

  4.     &wpa_driver_wext_ops,  // 我的系统使用的这个老的接口  

  5. #endif   

  6. #ifdef CONFIG_DRIVER_NL80211   // 现在流行的NL80211接口  

  7.     &wpa_driver_nl80211_ops,  

  8. #endif   

  9. #ifdef CONFIG_DRIVER_HOSTAP  

  10.     &wpa_driver_hostap_ops,  

  11. #endif   

  12. #ifdef CONFIG_DRIVER_MADWIFI  

  13.     &wpa_driver_madwifi_ops,  

  14. #endif   

  15. #ifdef CONFIG_DRIVER_BROADCOM  

  16.     &wpa_driver_broadcom_ops,  

  17. #endif   

  18. #ifdef CONFIG_DRIVER_BSD  

  19.     &wpa_driver_bsd_ops,  

  20. #endif   

  21. #ifdef CONFIG_DRIVER_NDIS  

  22.     &wpa_driver_ndis_ops,  

  23. #endif   

  24. #ifdef CONFIG_DRIVER_WIRED  

  25.     &wpa_driver_wired_ops,  

  26. #endif   

  27. #ifdef CONFIG_DRIVER_TEST  

  28.     &wpa_driver_test_ops,  

  29. #endif   

  30. #ifdef CONFIG_DRIVER_RALINK  

  31.     &wpa_driver_ralink_ops,  

  32. #endif   

  33. #ifdef CONFIG_DRIVER_OSX  

  34.     &wpa_driver_osx_ops,  

  35. #endif   

  36. #ifdef CONFIG_DRIVER_IPHONE  

  37.     &wpa_driver_iphone_ops,  

  38. #endif   

  39. #ifdef CONFIG_DRIVER_ROBOSWITCH  

  40.     &wpa_driver_roboswitch_ops,  

  41. #endif   

  42. #ifdef CONFIG_DRIVER_ATHEROS  

  43.     &wpa_driver_atheros_ops,  

  44. #endif   

  45. #ifdef CONFIG_DRIVER_NONE  

  46.     &wpa_driver_none_ops,  

  47. #endif   

  48.     NULL  

  49. };  

   具体选择哪一个driver,由wpa_supplicant的命令参数决定,如我的如下:
   在init.myboard.rc中定义:

 

[cpp] view plaincopy

  1. service wpa_supplicant /system/bin/wpa_supplicant \  

  2.     -Dwext -iwlan0 -c/data/misc/wifi/wpa_supplicant.conf  

  3.     #-Dnl80211 -iwlan0 -puse_p2p_group_interface=1 -e/data/misc/wifi/entropy.bin  

  4.     #   we will start as root and wpa_supplicant will switch to user wifi  

  5.     #   after setting up the capabilities required for WEXT  

  6.     #   user wifi  

  7.     #   group wifi inet keystore  

  8.     class main  

  9.     socket wpa_wlan0 dgram 660 wifi wifi  

  10.     disabled  

  11.     oneshot  

   由上可见,我的选择是wext, 即选择了:wpa_driver_wext_ops。具体选择在以下函数中实现,并最后保存在wpa_supplicant->driver中,以供在wpa_drv_scan中使用。

  首先需要讲解一下,在android4.0之后,wifi的工作方式基本都采用的是比较标准的nl80211方式,以前的wext方式现在使用的已经很少了,关于nl80211和wext的区别,小弟由于接触的少,所以简单的说两句(有错误的请各位大大指正啊,万谢!)

   wext:supplicant通过wext直接给wifi driver下命令,即不通过kernel,所以一般以wext工作的driver是不需要load cfg80211.ko的,这个cfg80211.ko就是kernel里面的wireless部分,主要对接supplicant和driver的。

   nl80211:supplicant的命令以nl80211的方式下给kernel,经过kernel再发送给driver,这样子做的好处是 supplicant和driver之间的通讯方式更加标准话,是以后的主流方式,我后面讲的driver都是以这种方式工作的。

[cpp] view plaincopy

  1. static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,  

  2.                      const char *name)  

  3. {  

  4.     int i;  

  5.     size_t len;  

  6.     const char *pos, *driver = name;  

  7.   

  8.     if (wpa_s == NULL)  

  9.         return -1;  

  10.   

  11.        wpa_msg(wpa_s,MSG_ERROR,"***MY_WIFI:%s,name=%s\n",__FUNCTION__,name);  

  12.       

  13.     if (wpa_drivers[0] == NULL) {  

  14.         wpa_msg(wpa_s, MSG_ERROR, "No driver interfaces build into "  

  15.             "wpa_supplicant");  

  16.         return -1;  

  17.     }  

  18.   

  19.     if (name == NULL) {  

  20.           

  21.         wpa_s->driver = wpa_drivers[0];  

  22.         wpa_s->global_drv_priv = wpa_s->global->drv_priv[0];  

  23.         return 0;  

  24.     }  

  25.   

  26.     do {  

  27.         pos = os_strchr(driver, ',');  

  28.         if (pos)  

  29.             len = pos - driver;  

  30.         else  

  31.             len = os_strlen(driver);  

  32.   

  33.         for (i = 0; wpa_drivers[i]; i++) {  

  34.             if (os_strlen(wpa_drivers[i]->name) == len &&  

  35.                 os_strncmp(driver, wpa_drivers[i]->name, len) ==  

  36.                 0) {  

  37.                 wpa_s->driver = wpa_drivers[i];  // 根据name进行匹配,并最后保存到wpa_supplicant->dirver中  

  38.                 wpa_s->global_drv_priv =  

  39.                     wpa_s->global->drv_priv[i];  

  40.                 return 0;  

  41.             }  

  42.         }  

  43.   

  44.         driver = pos + 1;  

  45.     } while (pos);  

  46.   

  47.     wpa_msg(wpa_s, MSG_ERROR, "Unsupported driver '%s'", name);  

  48.     return -1;  

  49. }  

2. 接口操作函数实现

2.1 用户态实现

  用户态实现的操作函数如下:

  实现代码见:/external/wpa_supplicant_8/wpa_supplicant/src/drivers/driver_wext.c

 

[cpp] view plaincopy

  1. const struct wpa_driver_ops wpa_driver_wext_ops = {  

  2.     .name = "wext",  

  3.     .desc = "Linux wireless extensions (generic)",  

  4.     .get_bssid = wpa_driver_wext_get_bssid,  

  5.     .get_ssid = wpa_driver_wext_get_ssid,  

  6. #ifdef WAPI  

  7.     .set_wapi = wpa_driver_wext_set_wapi,  

  8. #endif  

  9.     .set_key = wpa_driver_wext_set_key,  

  10.     .set_countermeasures = wpa_driver_wext_set_countermeasures,  

  11.     .scan2 = wpa_driver_wext_scan,  

  12.     .get_scan_results2 = wpa_driver_wext_get_scan_results,  

  13.     .deauthenticate = wpa_driver_wext_deauthenticate,  

  14.     .disassociate = wpa_driver_wext_disassociate,  

  15.     .associate = wpa_driver_wext_associate,  

  16.     .init = wpa_driver_wext_init, // 初始ioctl socket, netlink socket  

  17.     .deinit = wpa_driver_wext_deinit,  

  18.     .add_pmkid = wpa_driver_wext_add_pmkid,  

  19.     .remove_pmkid = wpa_driver_wext_remove_pmkid,  

  20.     .flush_pmkid = wpa_driver_wext_flush_pmkid,  

  21.     .get_capa = wpa_driver_wext_get_capa,  

  22.     .set_operstate = wpa_driver_wext_set_operstate,  

  23.     .get_radio_name = wext_get_radio_name,  

  24. #ifdef ANDROID  

  25.     .signal_poll = wpa_driver_signal_poll,  

  26.     .driver_cmd = wpa_driver_wext_driver_cmd, // 对应驱动中的 cfg80211_wext_setpriv  

  27. #endif  

  28. };  

.driver_cmd处理以DRIVER开始的命令,如:

   DRIVER MACADDR

   DRIVER BTCOEXSCAN-STOP

   DRIVER RXFILTER-ADD 3

   DRIVER RXFILTER-START

   DRIVER RXFILTER-STOP

   DRIVER RXFILTER-REMOVE 2

   DRIVER RXFILTER-START

  DRIVER SETBAND 0

   DRIVER SCAN-ACTIVE

   DRIVER SCAN-PASSIVE

  执行流程如下所示:

   wpa_supplicant_ctrl_iface_process-> (根据命令字符串调用对应的函数)

    wpa_supplicant_driver_cmd->

     wpa_drv_driver_cmd->

      wpa_s->driver->driver_cmd->

       wpa_driver_wext_driver_cmd-> (User)

      ...

       cfg80211_wext_setpriv(Kernel)

2.2 Kernel态实现    

   Kernel态实现的操作函数如下:

   实现代码见:net/wireless/wext_compat.c

 

[cpp] view plaincopy

  1. static const iw_handler cfg80211_handlers[] = {  

  2.     [IW_IOCTL_IDX(SIOCGIWNAME)] = (iw_handler) cfg80211_wext_giwname,  

  3.     [IW_IOCTL_IDX(SIOCSIWFREQ)] = (iw_handler) cfg80211_wext_siwfreq,  

  4.     [IW_IOCTL_IDX(SIOCGIWFREQ)] = (iw_handler) cfg80211_wext_giwfreq,  

  5.     [IW_IOCTL_IDX(SIOCSIWMODE)] = (iw_handler) cfg80211_wext_siwmode,  

  6.     [IW_IOCTL_IDX(SIOCGIWMODE)] = (iw_handler) cfg80211_wext_giwmode,  

  7.     [IW_IOCTL_IDX(SIOCGIWRANGE)]    = (iw_handler) cfg80211_wext_giwrange,  

  8.     [IW_IOCTL_IDX(SIOCSIWAP)]   = (iw_handler) cfg80211_wext_siwap,  

  9.     [IW_IOCTL_IDX(SIOCGIWAP)]   = (iw_handler) cfg80211_wext_giwap,  

  10.     [IW_IOCTL_IDX(SIOCSIWMLME)] = (iw_handler) cfg80211_wext_siwmlme,  

  11.     [IW_IOCTL_IDX(SIOCSIWSCAN)] = (iw_handler) cfg80211_wext_siwscan,  

  12.     [IW_IOCTL_IDX(SIOCGIWSCAN)] = (iw_handler) cfg80211_wext_giwscan,  

  13.     [IW_IOCTL_IDX(SIOCSIWESSID)]    = (iw_handler) cfg80211_wext_siwessid,  

  14.     [IW_IOCTL_IDX(SIOCGIWESSID)]    = (iw_handler) cfg80211_wext_giwessid,  

  15.     [IW_IOCTL_IDX(SIOCSIWRATE)] = (iw_handler) cfg80211_wext_siwrate,  

  16.     [IW_IOCTL_IDX(SIOCGIWRATE)] = (iw_handler) cfg80211_wext_giwrate,  

  17.     [IW_IOCTL_IDX(SIOCSIWRTS)]  = (iw_handler) cfg80211_wext_siwrts,  

  18.     [IW_IOCTL_IDX(SIOCGIWRTS)]  = (iw_handler) cfg80211_wext_giwrts,  

  19.     [IW_IOCTL_IDX(SIOCSIWFRAG)] = (iw_handler) cfg80211_wext_siwfrag,  

  20.     [IW_IOCTL_IDX(SIOCGIWFRAG)] = (iw_handler) cfg80211_wext_giwfrag,  

  21.     [IW_IOCTL_IDX(SIOCSIWTXPOW)]    = (iw_handler) cfg80211_wext_siwtxpower,  

  22.     [IW_IOCTL_IDX(SIOCGIWTXPOW)]    = (iw_handler) cfg80211_wext_giwtxpower,  

  23.     [IW_IOCTL_IDX(SIOCSIWRETRY)]    = (iw_handler) cfg80211_wext_siwretry,  

  24.  ..........................

  25.   

  26. const struct iw_handler_def cfg80211_wext_handler = {  

  27.     .num_standard       = ARRAY_SIZE(cfg80211_handlers),  

  28.     .standard       = cfg80211_handlers,  

  29.     .get_wireless_stats = cfg80211_wireless_stats,  

  30. };  


2.3 用户态与Kernel态的交互

    用户态向Kernel态发送请求时,通过ioctl来实现。

   Kernel态向用户态发送事件通知,通过netlink来实现。

   其交互的初始化在wpa_driver_wext_init中实现,其代码如下:

 

[cpp] view plaincopy

  1.   

  2. void * wpa_driver_wext_init(void *ctx, const char *ifname) // 我的ifname为wlan0  

  3. {  

  4.     struct wpa_driver_wext_data *drv;  

  5.     struct netlink_config *cfg;  

  6.     struct rfkill_config *rcfg;  

  7.     char path[128];  

  8.     struct stat buf;  

  9.   

  10.         wpa_printf(MSG_ERROR,"***MY_WIFI:%s,ifname=%s\n",__FUNCTION__,ifname);  

  11.       

  12.     drv = os_zalloc(sizeof(*drv));  

  13.     if (drv == NULL)  

  14.         return NULL;  

  15.     drv->ctx = ctx;  

  16.     os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));  

  17.   

  18.     os_snprintf(path, sizeof(path), "/sys/class/net/%s/phy80211", ifname);  

  19.     if (stat(path, &buf) == 0) {  

  20.         wpa_printf(MSG_DEBUG, "WEXT: cfg80211-based driver detected");  

  21.         drv->cfg80211 = 1;  

  22.         wext_get_phy_name(drv);  

  23.     }  

  24.   

  25.     drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);  // 此drv->ioctl_sock用作为ioctl命令的fd  

  26.     if (drv->ioctl_sock < 0) {  

  27.         perror("socket(PF_INET,SOCK_DGRAM)");  

  28.         goto err1;  

  29.     }  

  30.   

  31.     cfg = os_zalloc(sizeof(*cfg));  

  32.     if (cfg == NULL)  

  33.         goto err1;  

  34.     cfg->ctx = drv;  

  35.     cfg->newlink_cb = wpa_driver_wext_event_rtm_newlink;  

  36.     cfg->dellink_cb = wpa_driver_wext_event_rtm_dellink;  

  37.     drv->netlink = netlink_init(cfg);  // 初始化netlink,并注册事件接收函数  

  38.     if (drv->netlink == NULL) {  

  39.         os_free(cfg);  

  40.         goto err2;  

  41.     }  

  42.   

  43.     rcfg = os_zalloc(sizeof(*rcfg));  

  44.   

其中参数ifname在/data/misc/wifi/wpa_supplicant.conf中被定义,如我的如下:

[cpp] view plaincopy

  1. update_config=1  

  2. ctrl_interface=wlan0  

  3. eapol_version=1  

  4. ap_scan=1  

  5. fast_reauth=1  

2.3.1 ioctl实现方案

   在用户态可简单执行一个ioctl(fd,cmd,...)命令即可。

   在Kernel态则是通过唯一的cmd (SIOCIWFIRST--SIOCIWLAST) 来进行区分,从而执行cfg80211_handlers中对应的函数。

   socket文件操作如下:

 

[cpp] view plaincopy

  1.   

  2.   

  3. static const struct file_operations socket_file_ops = {  

  4.     .owner =    THIS_MODULE,  

  5.     .llseek =   no_llseek,  

  6.     .aio_read = sock_aio_read,  

  7.     .aio_write =    sock_aio_write,  

  8.     .poll =     sock_poll,  

  9.     .unlocked_ioctl = sock_ioctl, // 这个就是被执行的ioctl  

  10. #ifdef CONFIG_COMPAT  

  11.     .compat_ioctl = compat_sock_ioctl,  

  12. #endif  

  13.     .mmap =     sock_mmap,  

  14.     .open =     sock_no_open,     

  15.     .release =  sock_close,  

  16.     .fasync =   sock_fasync,  

  17.     .sendpage = sock_sendpage,  

  18.     .splice_write = generic_splice_sendpage,  

  19.     .splice_read =  sock_splice_read,  

  20. };  

从sock_ioctl到iw_handler的执行注程如下所示:

 sock_ioctl->

  dev_ioctl->

   wext_handle_ioctl-> (把执行结果从kernel态copy到用户态)

    wext_ioctl_dispatch->

     wireless_process_ioctl->

       1) get_handler

       2) ioctl_standard_call (执行cmd指定的iw_handler,并返回结果) 

 

2.3.2 用户态初始化netlink

 

[cpp] view plaincopy

  1. struct netlink_data * netlink_init(struct netlink_config *cfg)  

  2. {  

  3.     struct netlink_data *netlink;  

  4.     struct sockaddr_nl local;  

  5.   

  6.     netlink = os_zalloc(sizeof(*netlink));  

  7.     if (netlink == NULL)  

  8.         return NULL;  

  9.   

  10.     netlink->cfg = cfg;  

  11.   

  12.     netlink->sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);  

  13.     if (netlink->sock < 0) {  

  14.         wpa_printf(MSG_ERROR, "netlink: Failed to open netlink "  

  15.                "socket: %s", strerror(errno));  

  16.         netlink_deinit(netlink);  

  17.         return NULL;  

  18.     }  

  19.   

  20.     os_memset(&local, 0, sizeof(local));  

  21.     local.nl_family = AF_NETLINK;  

  22.     local.nl_groups = RTMGRP_LINK;  

  23.     if (bind(netlink->sock, (struct sockaddr *) &local, sizeof(local)) < 0)  

  24.     {  

  25.         wpa_printf(MSG_ERROR, "netlink: Failed to bind netlink "  

  26.                "socket: %s", strerror(errno));  

  27.         netlink_deinit(netlink);  

  28.         return NULL;  

  29.     }  

  30.   

  31.     eloop_register_read_sock(netlink->sock, netlink_receive, netlink,  

  32.                  NULL);  

  33.   

  34.     return netlink;  

  35. }  

2.3.3 用户态netlink事件接收函数netlink_receive

 

[cpp] view plaincopy

  1. static void netlink_receive(int sock, void *eloop_ctx, void *sock_ctx)  

  2. {  

  3.     struct netlink_data *netlink = eloop_ctx;  

  4.     char buf[8192];  

  5.     int left;  

  6.     struct sockaddr_nl from;  

  7.     socklen_t fromlen;  

  8.     struct nlmsghdr *h;  

  9.     int max_events = 10;  

  10.   

  11. try_again:  

  12.     fromlen = sizeof(from);  

  13.     left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT, //从netlink读取事件  

  14.             (struct sockaddr *) &from, &fromlen);  

  15.     if (left < 0) {  

  16.         if (errno != EINTR && errno != EAGAIN)  

  17.             wpa_printf(MSG_INFO, "netlink: recvfrom failed: %s",  

  18.                    strerror(errno));  

  19.         return;  

  20.     }  

  21.   

  22.     h =

  23. }  

3. SCAN流程

wpa_supplicant_ctrl_iface_process-> ( buf 内容为SCAN )

 wpa_supplicant_req_scan->wpa_supplicant_scan->wpa_supplicant_trigger_scan->wpa_drv_scan->wpa_s->driver->scan2->wpa_driver_wext_scan-> (Request the driver to initiate scan)wpa_driver_wext_combo_scan->ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr)-> (User)...cfg80211_wext_setpriv (cmd=CSCAN S)->cfg80211_wext_siwscan->rdev->ops->scan (cfg80211_ops mac80211_config_ops->scan)->ieee80211_scan-> ieee80211_request_scan->__ieee80211_start_scan->ieee80211_start_sw_scan-><1> drv_sw_scan_start->local->ops->sw_scan_start(ieee80211_ops ath9k_htc_ops->sw_scan_start)->ath9k_htc_sw_scan_start-> <2> ieee80211_hw_config-> (set power level at maximum rate for scanning)drv_config->local->ops->config( ieee80211_ops ath9k_htc_ops->config)-> ath9k_htc_config->ath9k_htc_setpower(priv,ATH9K_PM_AWAKE<3>  ieee80211_queue_delayed_work(&local->scan_work)->(注:INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work)) ieee80211_scan_work-> (根据local当前状态进行下一步工作,直到工作完成)__ieee80211_scan_completed-> (所有扫描的工作完成之后,调用此函数)drv_sw_scan_complete->local->ops->sw_scan_complete( ieee80211_ops ath9k_htc_ops->sw_scan_complete)ath9k_htc_sw_scan_complete


本文转载自:http://blog.sina.com.cn/s/blog_a6559d920101kcpn.html

共有 人打赏支持
s
粉丝 42
博文 202
码字总数 0
作品 0
深圳
高级程序员
wpa_supplicant与kernel交互

wpa_supplicant与kernel交互的操作,一般需要先明确驱动接口,以及用户态和kernel态的接口函数,以此来进行调用操作。这里分为4个步骤讨论。 1.首先需要明确指定的驱动接口。因为有较多的驱动...

sflfqx ⋅ 2014/07/29 ⋅ 0

wpa_supplicant 初始化流程分析

启动命令 wpa supplicant 在启动时,启动命令可以带有很多参数,目前我们的启动命令如下: wpasupplicant /system/bin/wpasupplicant -Dwext -ieth0 -c/data/wifi/wpasupplicant.conf -f/dat...

sflfqx ⋅ 2013/09/26 ⋅ 0

wpa_supplicant软件架构分析

struct socket 数据结构 interface network callback 目录(?)[+] 启动命令 wpa_supplicant 初始化流程 main函数 wpasupplicantinit函数 wpasupplicantadd_iface函数 wpasupplicantrun函数 Wp......

sflfqx ⋅ 2013/09/18 ⋅ 0

wpa_supplicant代码初探收藏

wpa_supplicant代码初探收藏 这几天在尝试把wpa_supplicant移植到windows ce上,替换微软的WZC。先把源代码down下来,了解了一下大致的结构。 wpasupplicant运行的整个核心就是elooprun函数。...

sflfqx ⋅ 2013/09/26 ⋅ 0

Android WiFi--系统架构

系统架构 Android WiFi系统引入了wpasupplicant,它的整个WiFi系统以wpasupplicant为核心来定义上层用户接口和下层驱动接口。整个WiFi系统架构如下图所示: 一切尽在上图中,下面将对每部分进...

sflfqx ⋅ 2014/04/10 ⋅ 0

wpa_supplicant学习

interface gtk makefile wrapper buffer methods 目录(?)[-] 本来以为这个东西只有在Atheros的平台上用的突然发现Ralink的平台也可以用甚至还看到还有老美把这个东西往android上移植看来是个...

sflfqx ⋅ 2013/09/26 ⋅ 0

android wifi工作流程

Wifi 网卡状态 1. WIFISTATEDISABLED: WIFI网卡不可用 2. WIFISTATEDISABLING: WIFI正在关闭 3. WIFISTATEENABLED:WIFI网卡可用 4. WIFISTATEENABLING:WIFI网卡正在打开 5. WIFISTATEUNKNOW......

sflfqx ⋅ 2013/03/11 ⋅ 0

Android WIFI 架构和控制流程

一、WIFI的基本架构 1、wifi用户空间的程序和库: external/wpa_supplicant/ 生成库libwpaclient.so和守护进程wpa_supplicant 2、hardware/libhardware_legary/wifi/是wifi管理库 3、JNI部分:...

鉴客 ⋅ 2011/08/24 ⋅ 4

Android: Android Wifi System

Wifi System: Java应用层 Java Framework层 JNI层 适配器层 wpa_supplicant程序 Kernel层 Java应用层 -- Settings, WifiSwitcher等应用 --> /system/app Java Framework层 -- frameworks/ba......

长平狐 ⋅ 2012/06/20 ⋅ 0

FC16下安装Linux版本的必联BL-LW05-H无线网卡驱动程序

大侠们好! 我在FC16下安装Linux版本的必联BL-LW05-H无线网卡驱动程序,根据文件包的readme_sta文件说明,应该操作下,我的问题在一旁有标注: 1> $tar -xvzf RT2870LinuxSTAx.x.x.x.tgz go...

0xtuhao ⋅ 2014/03/19 ⋅ 1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

在java中读取文件(也支持读取jar中的文件)

getClass().getResourceAsStream("文件名.格式"); 这个方法是用于获取当前类所在目录下的文件;需要将文件放到和当前类同一个包下面 比如我有个类在 com.test这个包下, 要读取一个test.jpg的图...

太黑_thj ⋅ 55分钟前 ⋅ 0

CentOS 7 源码编译安装 MySQL 5.7记录

没事瞎折腾,本来可以yum安装,却偏偏去要编译源码。 1. 安装依赖包 1). 安装cmake等依赖 # yum install cmake ncurses ncurses-devel bison bison-devel 2). 安装boost 1.59.0 # wget htt...

admin_qing ⋅ 57分钟前 ⋅ 0

tcp/ip详解-链路层

简介 设计链路层的目的: 为IP模块发送和接收IP数据报 为ARP模块发送ARP请求和接收ARP应答 为RARP模块发送RARP请求和接收RARP应答 TCP/IP支持多种链路层协议,如以太网、令牌环往、FDDI、RS-...

loda0128 ⋅ 今天 ⋅ 0

spring.net aop代码例子

https://www.cnblogs.com/haogj/archive/2011/10/12/2207916.html

whoisliang ⋅ 今天 ⋅ 0

发送短信如何限制1小时内最多发送11条短信

发送短信如何限制1小时内最多发送11条短信 场景: 发送短信属于付费业务,有时为了防止短信攻击,需要限制发送短信的频率,例如在1个小时之内最多发送11条短信. 如何实现呢? 思路有两个 截至到当...

黄威 ⋅ 昨天 ⋅ 0

mysql5.7系列修改root默认密码

操作系统为centos7 64 1、修改 /etc/my.cnf,在 [mysqld] 小节下添加一行:skip-grant-tables=1 这一行配置让 mysqld 启动时不对密码进行验证 2、重启 mysqld 服务:systemctl restart mysql...

sskill ⋅ 昨天 ⋅ 0

Intellij IDEA神器常用技巧六-Debug详解

在调试代码的时候,你的项目得debug模式启动,也就是点那个绿色的甲虫启动服务器,然后,就可以在代码里面断点调试啦。下面不要在意,这个快捷键具体是啥,因为,这个keymap是可以自己配置的...

Mkeeper ⋅ 昨天 ⋅ 0

zip压缩工具、tar打包、打包并压缩

zip 支持压缩目录 1.在/tmp/目录下创建目录(study_zip)及文件 root@yolks1 study_zip]# !treetree 11└── 2 └── 3 └── test_zip.txt2 directories, 1 file 2.yum...

蛋黄Yolks ⋅ 昨天 ⋅ 0

聊聊HystrixThreadPool

序 本文主要研究一下HystrixThreadPool HystrixThreadPool hystrix-core-1.5.12-sources.jar!/com/netflix/hystrix/HystrixThreadPool.java /** * ThreadPool used to executed {@link Hys......

go4it ⋅ 昨天 ⋅ 0

容器之上传镜像到Docker hub

Docker hub在国内可以访问,首先要创建一个账号,这个后面会用到,我是用126邮箱注册的。 1. docker login List-1 Username不能使用你注册的邮箱,要用使用注册时用的username;要输入密码 ...

汉斯-冯-拉特 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部