第二章 主机到网络层(网卡)--基于Linux3.10

2023-11-02

TCP/IP协议栈模型

网络协议栈常用OSI七层模型,实际上Linux网络协议栈使用的却是四层模型,图2.1展示了OSI七层和四层模型它们之间各层对应关系。图2.1的最左侧一列是数据在协议栈上各层的称谓。frame位于主机到网络层(Layer1),packet位于Layer2,segment位于Layer3,data或message位于Layer4;当然对于OSI七层模型而言,由下至上依次为Layer1~Layer7,即物理层为Layer1。


图2.1 TCP/IP协议栈的四层和七层模型

Layer1层对应到OSI七层模型是物理层,在四层模型中,这一层其实没有与之对应的层,这里偏重传输层和网络层,即tcp/ip协议栈。

网卡数据结构

和tcp/ip协议栈相比主机到网络层和硬件芯片打交道更多,因为这层的主要工作是转交给一个称为网卡(NIC)和PHY的硬件设备完成的,不同网卡性能还有区别,比如速率、offload、校验和、DMA、RSS、SG(scattergather)I/O等。内核将网卡应该具有的公共特性抽象成了一个称为net_device的结构体,因为各NIC(单网卡亦或集成与SOC的网卡)它们或多或少有些不同,现实应用中会将net_device实例、NIC特有特性、NIC特有功能封装到一个结构体内使用,使用register_netdev将net_device实例注册到内核。该结构体的定义如下:

1040 struct net_device{
1041 
1047     char            name[IFNAMSIZ];   //这个是网卡所呈现的接口的名称,如eth0、eth1等
1048 
1049     /* device name hash chain, please keep it close to name[] */
1050     struct hlist_node   name_hlist;
1051 
/*ifconfig命令配置别名时使用,在单网卡多接口用以区分网段时会使用到,在IPROUTE工具中,提供了新方法。*/
1053     char            *ifalias; 
/*网卡使用的内存、IO和中断信息*/
1059     unsigned long       mem_end;    /* shared mem end   */
1060     unsigned long       mem_start;  /* shared mem start */
1061     unsigned long       base_addr;  /* device I/O address   */
1062     unsigned int        irq;        /* device IRQ number    */

1071     struct list_head    dev_list; //设备链表
1072     struct list_head    napi_list; //napi链表
1073     struct list_head    unreg_list;
1074     struct list_head    upper_dev_list; /* List of upper devices */

 /*这些特性指,如分散聚集IO,UFO,校验和等等,见include/linux/netdev_features.h的17~71行。*/
1078     netdev_features_t   features; 
1079     /* user-changeable features */
1080     netdev_features_t   hw_features;
1081     /* user-requested features */
1082     netdev_features_t   wanted_features;

1092     /* Interface index. Unique device identifier    */
1093     int         ifindex;  //接口索引,每个设备对应一个唯一的索引值
1094     int         iflink;
1095 

/*该网卡相关的统计信息,如接收、发送的数据包总数相关信息等。netstat -i或者ifconfig看到的关于数据包统计信息源于此处。这些命令行根据在下篇有提及*/
1096     struct net_device_stats stats; 
1097     atomic_long_t       rx_dropped; /* dropped packets by core network
1098                          * Do not use this in drivers.
1099                          */
/*这里的ops非常重要,网卡发送接收数据的函数就在这里,不同的设备不同,这也是网络驱动编写者需要完成的工作。*/
1109     const struct net_device_ops *netdev_ops; 
1110     const struct ethtool_ops *ethtool_ops;  //ethtool工具的操作方法的集合。
1112     /* Hardware header description */
1113     const struct header_ops *header_ops; //
1114 
1115     unsigned int        flags;  /* interface flags (a la BSD)   */
1116     unsigned int        priv_flags; /* Like 'flags' but invisible to userspace.
1117                          * See if.h for definitions. */
1118     unsigned short      gflags;
1119     unsigned short      padded; /* How much padding added by alloc_netdev() */
1120 
1121     unsigned char       operstate; /* RFC2863 operstate */
1122     unsigned char       link_mode; /* mapping policy to operstate */
1123 
1124     unsigned char       if_port;    /* Selectable AUI, TP,..*/
1125     unsigned char       dma;        /* DMA channel      */
1126 
1127     unsigned int        mtu;    /* interface MTU value    其会影响到分片操作  */
1128     unsigned short      type;   /* interface hardware type  见if_arp.h文件*/
1129     unsigned short      hard_header_len;    /* hardware hdr length  */

1138     /* Interface address info. */
1139     unsigned char       perm_addr[MAX_ADDR_LEN]; /* permanent hw address */
1140     unsigned char       addr_assign_type; /* hw address assignment type */
1141     unsigned char       addr_len;   /* hardware address length  */
1142     unsigned char       neigh_priv_len;
1143     unsigned short          dev_id;     /* for shared network cards */

//混杂模式标志,即数据包目的地址非本机也会被收集到,wireshark、tcpdump会将网卡置于该工作模式
1156     unsigned int        promiscuity; 
1157     unsigned int        allmulti;
1169     struct in_device __rcu  *ip_ptr;    /* IPv4 specific data   */

1176 /*
1177  * Cache lines mostly used on receive path (including eth_type_trans())
1178  */
1179     unsigned long       last_rx;    /* Time of last Rx
1180                          * This should not be set in
1181                          * drivers, unless really needed,
1182                          * because network stack (bonding)
1183                          * use it if/when necessary, to
1184                          * avoid dirtying this cache line.
1185                          */
1186 
1187     /* Interface address info used in eth_type_trans() */
1188     unsigned char       *dev_addr;  /* hw address, (before bcast    MAC地址
1189                            because most packets are
1190                            unicast) */
/发送队列的记录信息*/
1214     struct netdev_queue *_tx ____cacheline_aligned_in_smp;
1215 
1216     /* Number of TX queues allocated at alloc_netdev_mq() time  */
1217     unsigned int        num_tx_queues;
1218 
1219     /* Number of TX queues currently active in device  */
1220     unsigned int        real_num_tx_queues;
1221 
1222     /* root qdisc from userspace point of view */
1223     struct Qdisc        *qdisc; //queue discipline,会影响数据包的收发。
1224 
1225     unsigned long       tx_queue_len;   /* Max frames per queue allowed */
1226     spinlock_t      tx_global_lock;

/*register_netdevice注册该网卡,ifconfig up/down等,会修改网卡的设备的状态,所有状态均在此。*/
1259     /* register/unregister state machine */
1260     enum { NETREG_UNINITIALIZED=0,
1261            NETREG_REGISTERED,   /* completed register_netdevice */
1262            NETREG_UNREGISTERING,    /* called unregister_netdevice */
1263            NETREG_UNREGISTERED, /* completed unregister todo */
1264            NETREG_RELEASED,     /* called free_netdev */
1265            NETREG_DUMMY,        /* dummy device for NAPI poll */
1266     } reg_state:8;   1267 
1268     bool dismantle; /* device is going do be freed */
1269 
1270     enum {
1271         RTNL_LINK_INITIALIZED,
1272         RTNL_LINK_INITIALIZING,
1273     } rtnl_link_state:16; //rtnl,是route Netlink的缩写,描述其状态。
1274 
1282 #ifdef CONFIG_NET_NS
1283     /* Network namespace this network device is inside */
1284     struct net      *nd_net; //网络命名空间,container机制会用到
1285 #endif
1286 
1287     /* mid-layer private */
1288     union {
1289         void                *ml_priv; 

/*注意这里的__percpu,这就意味着这些成员再SMP情况下,每个CPU核都有一个副本以提高效率*/
1290         struct pcpu_lstats __percpu *lstats; /* loopback stats */   
1291         struct pcpu_tstats __percpu *tstats; /* tunnel stats */
1292         struct pcpu_dstats __percpu *dstats; /* dummy stats */
1293         struct pcpu_vstats __percpu *vstats; /* veth stats */
1294     };

1300     /* class/net/name entry */
1301     struct device       dev; // 通用的设备模型结构体,该结构体描述的是设备都需要的成员

1305     /* rtnetlink link ops */
1306     const struct rtnl_link_ops *rtnl_link_ops; //ip和tc工具的内核支持机制Netlink的操作集
1307 
1308     /* for setting kernel sock attribute on TCP connection setup */

/*GSO 是generic segment offload,是TSO(TCP segment offload)的升级,segment数据原本在TCP层,但是为了效率,现在网卡自己支持分片操作,所以有些情况下会将分片操作推迟到网卡去完成。这些网络多队列等新特性在下部中会提及*/
1309 #define GSO_MAX_SIZE        65536                   
1310     unsigned int        gso_max_size;                    
1311 #define GSO_MAX_SEGS        65535
1312     u16         gso_max_segs;

/*拥塞控制相关*/
1318     u8 num_tc;
1319     struct netdev_tc_txq tc_to_txq[TC_MAX_QUEUE];
1320     u8 prio_tc_map[TC_BITMASK + 1]; 
1321 

1329     /* phy device may attach itself for hardware timestamping */
//PHY内容,参看十六章。
1330     struct phy_device *phydev; 
1338 };

该数据结构占298行,是Linux内核中比较大的数据结构了,该结构主要就是描述网卡的状态、能力、操作集、用户空间的接口支持等。网卡的函数操作集如下:

 906 struct net_device_ops {
//当网卡注册时仅会调用一次,该函数用于进一步的完成设备特定的初始化工作。
 907     int         (*ndo_init)(struct net_device *dev);                
 908     void            (*ndo_uninit)(struct net_device *dev);         //网卡注销或者注册失败时调用。
 //打开网卡时会调用,ifconfig,ip等命令会触发,当将网卡转到up时调用。 
909     int         (*ndo_open)(struct net_device *dev);            
 910     int         (*ndo_stop)(struct net_device *dev);               //当将网卡转到down时调用。
 911     netdev_tx_t     (*ndo_start_xmit) (struct sk_buff *skb, 
 912                            struct net_device *dev);                  //图2.1中的frame就是通过该函数发送到RJ45线上(实际上是配置网卡内部发送寄存器,启动硬件发送)
 918     int         (*ndo_set_mac_address)(struct net_device *dev,
 919                                void *addr);
 920     int         (*ndo_validate_addr)(struct net_device *dev);
 921     int         (*ndo_do_ioctl)(struct net_device *dev,
 922                             struct ifreq *ifr, int cmd);                 //ifconfig使用的ioctl方法,会调用该接口将命令发送到网卡,但是ip和tc工具使用Netlink方法和此不同。
 923     int         (*ndo_set_config)(struct net_device *dev,
 924                               struct ifmap *map); 
... 
}

header_ops用于协议的头部信息处理,处理方式如下:

 265 struct header_ops {
 266     int (*create) (struct sk_buff *skb, struct net_device *dev,
 267                unsigned short type, const void *daddr,
 268                const void *saddr, unsigned int len);                   //创建一个协议头
 269     int (*parse)(const struct sk_buff *skb, unsigned char *haddr);  //获得packet包对应的硬件地址,集MAC地址。
 270     int (*rebuild)(struct sk_buff *skb);
 271     int (*cache)(const struct neighbour *neigh, struct hh_cache *hh, __be16 type);
 272     void    (*cache_update)(struct hh_cache *hh,
 273                 const struct net_device *dev,
 274                 const unsigned char *haddr);
 275 };

网卡注册流程

上面的网卡数据结构在网卡驱动架构中是处于核心的地位,在注册网卡时就使用到了,TCP/IP网络协议栈的Layer1还是比较重要的,毕竟所有的数据均通过这里,下面是网卡的注册流程,绝大多数情况下网卡的注册实际上就是MAC控制器的注册,通常会外接PHY芯片,补充一下这里注册实例:

1、这里给的例子基于SOC芯片上的MAC控制器注册。其不挂载在PCI总线上。

2、通常意义上常说的网络驱动程序编写也指的是下面所写的内容,由于是设备驱动代码了,所以代码不再net目录下,而在drivers目录下了。

drivers/net/ethernet/目录下的代码,该目录下每个厂商会对应一个子目录。

网卡注册流程:

static struct platform_driver XXYY_driver = {
.probe  = XXYY_drv_probe,
.remove  = XXYY_drv_remove,
   .driver = {
   .name = "XXYY-eth",
   .owner  = THIS_MODULE,
   .of_match_table= XXYY_eth_dt_ids,
   },
};
module_platform_driver(XXYY_driver); 

module_platform_driver在注册设备驱动时,会调用回调函数probe完成特定硬件设备需要的一些工作,代码框架如下:

static int XXYY_drv_probe(struct platform_device *pdev) 
{
/* device_node 设备树相关*/
struct device_node *np = pdev->dev.of_node;
struct net_device *ndev;
struct XXYY_info *lp;
struct resource *res;
const char *macaddr;
int ret_val = 0;
/*XXYY_info是对net_device结构体的封装*/
ndev = alloc_etherdev(sizeof(struct XXYY_info)); //
lp = netdev_priv(ndev);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
lp->regbase = devm_ioremap(&pdev->dev, res->start, resource_size(res));
ndev->irq = platform_get_irq(pdev, 0);    //如果中断使能,那么在接收和发送数据包时会用到该中断号。
lp->ndev = ndev;
lp->mii_bus.read = &XXYY_mdio_read,   //PHY设备读写,参考《PHY Linux 驱动》
lp->mii_bus.write = &XXYY_mdio_write,
lp->mii_bus.reset = &XXYY_mdio_reset,
ret_val = of_mdiobus_register(&lp->new_bus, pdev->dev.of_node);
lp->phydev = phy_find_first(&lp->new_bus);
ether_setup(ndev);    //该函数用于初始化以太网设备通用的字段,见后面讲述。
//这里再一次看见了struct net_device_ops 结构体,这是需要驱动程序编写者根据芯片手册完成的。
ndev->netdev_ops = &ambeth_netdev_ops;   
netif_napi_add(ndev, &lp->napi, XXYY_napi, XXYY_NAPI_WEIGHT); //NAPI主机到网络层再来看这里的意义。
ret_val = register_netdev(ndev);  //前文所述的将网络设备注册到Linux核心的函数。
platform_set_drvdata(pdev, ndev);  //platform 总线上的信息记录
return 0;
}

ether_setup(ndev),该函数用于初始化以太网设备通用的字段,函数的如下:

void ether_setup(struct net_device *dev) 
{
dev->header_ops= ð_header_ops;
dev->type  = ARPHRD_ETHER;
dev->hard_header_len = ETH_HLEN;
dev->mtu  = ETH_DATA_LEN;
dev->addr_len  = ETH_ALEN;
dev->tx_queue_len= 1000; 
/* Ethernet wants good queues */
dev->flags  = IFF_BROADCAST|IFF_MULTICAST;
dev->priv_flags|= IFF_TX_SKB_SHARING;
memset(dev->broadcast, 0xFF, ETH_ALEN);
}

函数的操作集如下:

static const struct net_device_ops XXYY _netdev_ops = {
.ndo_open  = XXYY_open,
.ndo_stop  = XXYY_stop,
.ndo_start_xmit= XXYY_hard_start_xmit,
.ndo_set_rx_mode= XXYY_set_multicast_list,
.ndo_set_mac_address  = XXYY_set_mac_address,
.ndo_validate_addr= eth_validate_addr,
.ndo_do_ioctl  = XXYY_ioctl,
.ndo_change_mtu= eth_change_mtu,
.ndo_tx_timeout= XXYY_timeout,
.ndo_get_stats= XXYY_get_stats,
};

netif_napi_add添加一个napi服务函数。

void netif_napi_add(struct net_device *dev, struct napi_struct *napi,
   int (*poll)(struct napi_struct *, int), int weight)
{
INIT_LIST_HEAD(&napi->poll_list);
napi->gro_count = 0;
napi->gro_list = NULL;
napi->skb = NULL;
napi->poll = poll;
napi->weight = weight;
list_add(&napi->dev_list, &dev->napi_list);
napi->dev = dev;
set_bit(NAPI_STATE_SCHED, &napi->state);
}

注册完毕后,PHY设备通过自协商选择合适的网络速率,MAC层这时也注册到Linux核心了,网卡和数据以及PHY的关联,见图1.2。

图1.2 网卡结构体关键字段组织

该图中的sk_buff,在Linux内核代码中通常将sk_buff注释成SKB,后面沿用此注释法。SKB存放数据,发送和接收维护各自的队列,虽然通常一个网卡的接收和发送使用同一套DAM控制器,但是其接收和发送数据包的缓存是区分开的。XXYY_netdev_ops结构体中并没有接收数据包的方法,其实由于数据包到达时刻的不确定性而采用了中断的方式接收数据,为了节约中断资源,在XXYY_open中才注册中断服务函数,通常其它类型的设备驱动程序都是这么做的,在close设备时,将中断号释放掉,以便其它设备可以使用该中断号。open函数的原型如下:

static int XXYY_open(struct net_device *ndev)
{
int ret_val = 0;
struct XXYY_info *lp;

lp = (struct XXYY_info *)netdev_priv(ndev);
ret_val = XXYY_start_hw(ndev);  //特定于SOC的函数,配置相关寄存器使能该网卡设备
ret_val = request_irq(ndev->irq, XXYY_interrupt,
//注册中断服务函数,发送和接收共享该中断,服务函数中判断是接收还是发送中断。
IRQF_SHARED | IRQF_TRIGGER_HIGH, ndev->name, ndev);   
napi_enable(&lp->napi);   //NAPI接口
netif_start_queue(ndev);   //发送使能
netif_carrier_off(ndev);  
ret_val = XXYY_phy_start(lp); //复位一下PHY设备
return ret_val;
}

接收中断调度NAPI,发送中断则执行发送端代码,napi主体思想如下:

l  常规流程在接收数据包时,一个数据包到达网卡时,网卡产生中断,通知CPU数据到来,CPU响应该次接收,当下一个数据包到来时,再次重复上述过程,这个过程的特点是一个中断对应一个数据包,为了省去中断带来的资源开销,能不能一个中断多收几个数据包呢?轮询就可以实现一个中断接收多个数据包,流程变为当数据包到来产生中断时, CPU关中断,不停的轮询网卡是否有新数据到来,接收数据包个数的上限值(和网卡接收缓存大小相关,常取buffer的2/3~1/3之间)或者超时可以作为退出条件。

l  发送也是这么概念,一次发送缓冲区大小的1/3~2/3,然后再使能发送中断,网卡发送完数据后会产生发送中断。

static inline void XXYY_interrupt_rx(struct XXYY_info *lp, u32 irq_status)
{
napi_schedule(&lp->napi);
}

napi所完成的工作就是实质将数据向上层发送

static inline void XXYY_napi_rx(struct ambeth_info *lp, u32 status, u32 entry)
{
   struct sk_buff *skb; 
   skb = lp->rx.rng_rx[entry].skb; 
   netif_receive_skb(skb);  //该函数将数据从主机到网络发送到网络层
}

netif_receive_skb(skb); 该函数将数据从主机到网络层发送到网络层,即IP层;其调用__netif_receive_skb将NAPI(napi_struct)方法添加到轮询表,并设置软中断NET_RX_SOFTIRQ。软中断服务函数net_rx_action将会执行poll函数,关闭中断并轮询网卡,超时或者接收数据包数量超限时会退出。

IP层发送数据到主机到网络层使用的接口函数是:

intdev_queue_xmit(struct sk_buff *skb),还会经过流控环节,路由也会咨询一些流控信息。这个接口是IP和主机到网络层的接口,后面还会遇到。和IP层连通的函数是ip_rcv()和ip_out(),下面以一张图来结束本章的内容。





图1.3 网卡注册流程






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

第二章 主机到网络层(网卡)--基于Linux3.10 的相关文章

  • 从 gitlab docker runner 启动声纳扫描仪

    我有一个 CI 工作流程 集成了 linting 作业和代码质量作业 我的 Linting 工作是一个 docker runner 从应用程序代码启动我的 eslint 脚本 然后我的代码质量工作应该启动声纳扫描仪泊坞窗实例 检查我的代码并
  • Linux:通过网络进行屏幕桌面视频捕获和 VNC 帧速率

    抱歉 文字墙很长 TL DR VNC 连接的帧速率是多少 以帧 秒为单位 或者更确切地说 由谁决定 客户端还是服务器 对于桌面屏幕捕获的任何其他建议 但 正确的时间编码 具有不抖动的帧速率 具有稳定的周期 并有可能将其作为未压缩 或无损 图
  • 使用 linux perf 工具测量应用程序的 FLOP

    我想使用 perf Linux 性能计数器子系统的新命令行接口命令 来测量某些应用程序执行的浮点和算术运算的数量 出于测试目的 我使用了我创建的一个简单的虚拟应用程序 请参见下文 因为我找不到任何为测量 FP 和整数运算而定义的 perf
  • 如何真正释放 Linux 中的大页面以供新进程使用?

    真的找不到太多关于此的信息 希望有人可以提供帮助 我正在假脱机使用 100GB java 堆作为大数据缓存 为了避免与文件系统缓存等内容发生冲突 并且因为它通常性能更好 我将其分配在大页面中 我保留了 51 200 x 2MB 大页面 一切
  • 如何“grep”连续流?

    可以用吗grep在连续的流中 我的意思是有点tail f
  • Snap-confine 具有提升的权限,并且不受限制,但应该受到限制。拒绝继续避免权限升级攻击

    我已经使用 snap 一段时间了 但最近升级后 当我尝试打开任何应用程序时 出现此错误 Snap confine has elevated permissions and is not confined but should be Refu
  • 是否可以找到哪个用户位于 localhost TCP 连接的另一端?

    这是一个编程问题 但它是 Linux Unix 特定的 如果我从本地主机获得 TCP 连接 是否有一种简单的方法可以告诉哪个用户在 C 程序内建立了连接而无需 shell 我知道这对于 Unix 域套接字来说并不太难 我已经知道远程 IP
  • 为什么使用Python的os模块方法而不是直接执行shell命令?

    我试图了解使用Python的库函数执行特定于操作系统的任务 例如创建文件 目录 更改文件属性等 背后的动机是什么 而不是仅仅通过执行这些命令os system or subprocess call 例如 我为什么要使用os chmod而不是
  • 我在哪里可以学习如何使 C++ 程序与操作系统 (Linux) 交互

    我是一个 C 初学者 我想创建与操作系统交互的小程序 使用 Kubuntu Linux 到目前为止 我还没有找到任何教程或手册来让 C 与操作系统交互 在 PHP 中 我可以使用命令 exec 或反引号运算符来启动通常在控制台中执行的命令
  • 原生 Linux 应用程序可像 ResHacker 一样编辑 Win32 PE

    我想运行自动修改 dll服务 用户提交特定的 dll 我在服务器上修改它 然后用户可以下载 dll的修改版本 是否有任何本机 Linux 应用程序提供常见的 Win32 PE 修改功能 例如图标 字符串 加速器 对话等 至少提供命令行或脚本
  • 在中断时获取 current->pid

    我正在Linux调度程序上写一些东西 我需要知道在我的中断到来之前哪个进程正在运行 当前的结构可用吗 如果我在中断处理程序中执行 current gt pid 我是否可以获得我中断的进程的 pid 你可以 current gt pid存在并
  • 如何阅读shell命令的源代码?

    我想阅读编写linux命令的实际源代码 我已经获得了一些使用它们的经验 现在我认为是时候与我的机器进行更深层次的交互了 我在这里找到了一些命令http directory fsf org wiki GNU http directory fs
  • Linux 文本文件操作

    我有一个格式的文件 a href a href a href a href 我需要选择 之后但 之前的文本 并将其打印在行尾 添加后 例如 a href http www wowhead com search Su a a a a a
  • Gradle 1.3:build.gradle 不构建类

    这里有一个新问题 我有一个 build gradle 文件apply plugin java在其中 并与 java 项目 包关联 当我跑步时gradle build从命令行我得到 compileJava UP TO DATE process
  • Linux 中的电源管理通知

    在基于 Linux 的系统中 我们可以使用哪些方法 最简单的方法 来获取电源状态更改的通知 例如 当计算机进入睡眠 休眠状态等时 我需要这个主要是为了在睡眠前保留某些状态 当然 在计算机唤醒后恢复该状态 您只需配置即可获得所有这些事件acp
  • Linux、ARM:为什么仅当启动时存在 I2C GPIO 扩展器时才创建 gpiochip

    在 imx6sx 硬件平台 NXP 嵌入式 ARM 上使用 Linux 3 14 52 问题是设备树中指定的 PCF8575 I2C GPIO 扩展器不会实例化为 sys class gpio 结构中的设备 除非它们在内核启动期间存在 这些
  • perf stat中的cycles注释是什么意思

    8 014196 task clock 0 004 CPUs utilized 204 context switches 0 025 M sec 32 cpu migrations 0 004 M sec 0 page faults 0 0
  • 在 shell 脚本中查找和替换

    是否可以使用 shell 在文件中搜索然后替换值 当我安装服务时 我希望能够在配置文件中搜索变量 然后在该值中替换 插入我自己的设置 当然 您可以使用 sed 或 awk 来完成此操作 sed 示例 sed i s Andrew James
  • 用于验证 InetSocketAddresses 的正则表达式(ipv4/v6 + 端口地址)

    我在寻找testedipv4 和 ipv6 的正则表达式InetSocket地址 http download oracle com javase 6 docs api java net InetSocketAddress html toSt
  • 进程名称长度的最大允许限制是多少?

    进程名称允许的最大长度是多少 我正在读取进程名称 proc pid stat文件 我想知道我需要的最大缓冲区 我很确定有一个可配置的限制 但就是找不到它在哪里 根据man 2 prctl http man7 org linux man pa

随机推荐

  • Python 回调函数实现异步处理

    说到异步处理大家应该会联想到Ajax 处理 那我们先来说说什么是Ajax 请求 Ajax 就相当于是模拟了一个信息发送请求 你可以在很多网站上注册的时候会发现 比如用户名输入 123 那么它可能会提示你该用户已经存在 而给你的感觉是页面并没
  • windows、Ubuntu安装QT时经常出现“无法下载存档……”解决办法

    说明 以windows为例 ubuntu操作一样 下载好exe执行文件 双击执行时 经常出现下图提示 无法下载存档 是由于默认使用的是境外源 有两种解决方式 方式一 挂魔法在线安装 方式二 使用国内源 清华大学 https mirrors
  • 读阮一峰ES6对象解构赋值小细节

    最近看阮一峰的ES6发现了个地方有点不懂 理解之后 特意记录下来 let obj let arr foo obj prop bar arr 0 foo 123 bar true obj prop 123 arr true 就是上面这块 首先
  • NavicatPremium连接MySQL出现异常Authentication plugin ‘caching_sha2_password‘ cannot be loaded的解决方案

    一 出现异常原因 由于个人本机安装的mysql是8 0 在使用Navicat连接数据库时 出现Authentication plugin caching sha2 password cannot be loaded异常 通过搜集资料得知my
  • 几种常用的无源滤波器的特征

    无源滤波器的缺点 带负载能力差 无放大作用 特性不理想 边沿不陡峭 各级相互影响 滤波器是一种通过一定频率的信号而阻止或衰减其他频率信号的部件 分类 按照处理信号形式 模拟滤波器和数字滤波器 按功能分 低通 高通 带通 带阻 按电路组成分
  • Visio中实现任意两点之间的连线

    参考博客01 https blog csdn net wanzhen4330 article details 84837279 想实现的效果 如下图所示 想要实现的是像下面图中 让箭头线段多次弯折 最终连接两个矩形方框 二 做法 在Visi
  • SQLServer数据库密码已过期问题 处理

    Sqlserver在设置登录账户信息的时候 有个复选框信息会被默认勾上 即强制实施密码策略 默认勾选上的还有强制密码过期 如果勾上了这个强制密码过期后 则你的账户密码在一定时间登录后会提示Sqlserver登录密码已过期请重新设置密码 如果
  • docker-management遇到的一些问题

    一个mysql节点 两个cloudstack management节点 先启动mysql节点 如果cloudstack management容器节点无法访问mysql节点 注意docker宿主机的iptables规则 启动cloudstac
  • 总结一波安卓组件化开源方案

    摘要 为了让大家能快速对android组件化有个整体的认识 本文将从多个维度对目前网上一些有代表性的开源组件化开发方案进行对比 从而更好的区分各组件化方案的特点 快速选择适合自己使用的方案深入学习并使用 在面试中被问到时也能做到心中有数 前
  • PCL 从深度图像中提取边界

    一 图像边界 深度图像边界 计从前景跨越到背景的位置定义为边界 具体有 物体边界 这是物体的最外层和阴影边界的可见点集 阴影边界 毗邻与遮挡的背景上的点集 Veil点集 在被遮挡物边界和阴影边界之间的内插点 它们是有激光雷达获取的3D距离数
  • docker基础6——制作镜像(dockerfile)

    文章目录 一 基本了解 1 1 基于centos构建镜像 1 2 基于alpine制作镜像 二 常用指令 三 制作httpd镜像 一 基本了解 Dockerfile 是一个文本格式的配置文件 可以使用Dockerfile 快速创建自定义镜像
  • 飞机降落(dfs 全排列)

    题目描述 N 架飞机准备降落到某个只有一条跑道的机场 其中第 i 架飞机在 Ti 时刻到达机场上空 到达时它的剩余油料还可以继续盘旋 Di 个单位时间 即它最早 可以于 Ti 时刻开始降落 最晚可以于 Ti Di 时刻开始降落 降落过程需要
  • C# 枚举 enum(学习心得 17)

    枚举是一组命名整型常量 枚举类型是使用 enum 关键字声明的 C 枚举是值类型 枚举包含自己的值 且不能继承或传递继承 超级小白友好 讲解C 基础 每集5分钟轻松学习 拒绝从入门到放弃 声明 enum
  • linux服务器无法ssh怎么解决,linux服务器有可能无法连接ssh

    新安装的linux服务器有可能无法连接ssh 这可是怎么办 我的服务器是centOS6 9的版本 1 首先关闭 SELINUX vi etc selinux config SELINUX enforcing 注释掉 SELINUXTYPE
  • SpringBoot三种注解启动方式

    1 SpringBoot内置了Tomcat Jetty等容器 所以可以通过注解方式进行启动 2 SpringBoot注解启动的原理 SpringBoot main方法 是程序入口 启动SpringBoot项目 创建内置tomcat服务器 使
  • windows 10 webrtc 下载与编译以及遇到的问题

    下载 1 由于webrtc 源码在 墙外 所以需要科学上网 自行解决 当然现在webrtc 有国内的镜像地址 https webrtc org cn mirror 内附编译下载教程自行查阅 下载后只包含M79 和最新的master 分支 由
  • dao层动态sql利器!数据持久化jpa插件spring-data-jpa-extra?Fenix!

    把hibernate mybatis都整合到一个项目中 有没有觉得臃肿繁琐 我们知道 dao层 会用数据持久化框架 如hibernate mybatis等 他们都实现了jpa规范 几年来 spring想统领这个层 有spring jpa d
  • 追踪邮件发送者的地理位置

    今天偶然发现Gmail可以追踪发送者的IP位置 于是忍不住跃跃欲试 邮件不只有文本内容 还有额外的信息在每个邮件的header里面 一般的邮件客户端都是不能查看header的 Gmail和雅虎邮箱可以 网易邮箱的查看信头也能实现 打开Gma
  • 【GitHubShare】Web 前后端开发、以太坊基础、智能合约、密码学、数据分析

    区块链开发指南 作者通过 NFT 进行募资 然后将资金用于激励社区创作 让参与教程编写的人都能获益 从项目创建之初 教程便一直保持开放 GitHub github com dcbuild3r blockchain development g
  • 第二章 主机到网络层(网卡)--基于Linux3.10

    TCP IP协议栈模型 网络协议栈常用OSI七层模型 实际上Linux网络协议栈使用的却是四层模型 图2 1展示了OSI七层和四层模型它们之间各层对应关系 图2 1的最左侧一列是数据在协议栈上各层的称谓 frame位于主机到网络层 Laye